Subject: [RFC] Decrease server health based on http responses / events, version 
2

This RFC quality patch implements decreasing server health based on
observing communication between HAProxy and servers.

Changes in this version:
 - documentation
 - close race between a started check and health analysis event
 - don't force fastinter if it is not set
 - better names for options
 - layer4 support

Possibility to set/change default options is going to be implemented in
a different patch.

diff --git a/doc/configuration.txt b/doc/configuration.txt
index ef768f8..bdb5c78 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -4642,6 +4642,13 @@ cookie <value>
   the same cookie value, and it is in fact somewhat common between normal and
   backup servers. See also the "cookie" keyword in backend section.
 
+error_limit <count>
+  If health observing is enabled, the "error_limit" parameter specifies the 
number
+  of consecutive errors that triggers event selected by the "on-error" option.
+  By default it is set to 10 consecutive errors.
+
+ See also the "check", "error_limit" and "on-error".
+
 fall <count>
   The "fall" parameter states that a server will be considered as dead after
   <count> consecutive unsuccessful health checks. This value defaults to 3 if
@@ -4707,9 +4714,31 @@ minconn <minconn>
   the ramp between both values when the backend has less than <fullconn>
   concurrent connections. This makes it possible to limit the load on the
   server during normal loads, but push it further for important loads without
-  overloading the server during exceptionnal loads. See also the "maxconn"
+  overloading the server during exceptional loads. See also the "maxconn"
   and "maxqueue" parameters, as well as the "fullconn" backend keyword.
-  
+
+observe <mode>
+  This option enables health adjusting based on observing communication with
+  the server. By default this functionality is disabled and enabling it also
+  requires to enable healt checks. There are two supported modes: "layer4" and
+  "layer7". In layer4 mode, only successful/unsuccessful tcp connections are
+  significant. In layer7, which is only allowed for http proxies, responses
+  received from server are verified, like valid/wrong http code, unparsable
+  headers, a timeout, etc.
+
+  See also the "check", "on-error" and "error_limit".
+
+on-error <mode>
+  Select what should happen when enough consecutive errors are detected.
+  Currently, four modes are available:
+  - fastinter: force fastinter
+  - fail-check: simulate a failed check, also forces fastinter (default)
+  - sudden-death: simulate a pre-fatal failed health check, one more failed
+    check will mark a server down, forces fastinter
+  - mark-down: mark the server immediately down and force fastinter
+
+  See also the "check", "observe" and "error_limit".
+
 port <port>
   Using the "port" parameter, it becomes possible to use a different port to
   send health-checks. On some servers, it may be desirable to dedicate a port
diff --git a/include/common/defaults.h b/include/common/defaults.h
index b0aee86..cada729 100644
--- a/include/common/defaults.h
+++ b/include/common/defaults.h
@@ -120,6 +120,9 @@
 #define DEF_CHECK_REQ   "OPTIONS / HTTP/1.0\r\n\r\n"
 #define DEF_SMTP_CHECK_REQ   "HELO localhost\r\n"
 
+#define DEF_HANA_ONERR         HANA_ONERR_FAILCHK
+#define DEF_HANA_ERRLIMIT      10
+
 // X-Forwarded-For header default
 #define DEF_XFORWARDFOR_HDR    "X-Forwarded-For"
 
diff --git a/include/proto/checks.h b/include/proto/checks.h
index bd70164..e3fe7ac 100644
--- a/include/proto/checks.h
+++ b/include/proto/checks.h
@@ -29,6 +29,7 @@ const char *get_check_status_description(short check_status);
 const char *get_check_status_info(short check_status);
 struct task *process_chk(struct task *t);
 int start_checks();
+void health_adjust(struct server *s, short status);
 
 #endif /* _PROTO_CHECKS_H */
 
diff --git a/include/types/checks.h b/include/types/checks.h
index 1b04608..ac784dd 100644
--- a/include/types/checks.h
+++ b/include/types/checks.h
@@ -18,6 +18,9 @@ enum {
 
        /* Below we have finished checks */
        HCHK_STATUS_CHECKED,            /* DUMMY STATUS */
+
+       HCHK_STATUS_HANA,               /* Healt analyze detected enough 
consecutive errors */
+
        HCHK_STATUS_SOCKERR,            /* Socket error */
 
        HCHK_STATUS_L4OK,               /* L4 check passed, for example tcp 
connect */
@@ -41,8 +44,51 @@ enum {
        HCHK_STATUS_SIZE
 };
 
+
+/* healt status for response tracking */
+enum {
+       HANA_STATUS_UNKNOWN     = 0,
+
+       HANA_STATUS_L4_OK,              /* L4 successful connection */
+       HANA_STATUS_L4_ERR,             /* L4 unsuccessful connection */
+
+       HANA_STATUS_HTTP_OK,            /* Correct http response */
+       HANA_STATUS_HTTP_STS,           /* Wrong http response, for example 
HTTP 5xx */
+       HANA_STATUS_HTTP_HDRRSP,        /* Invalid http response (headers) */
+       HANA_STATUS_HTTP_RSP,           /* Invalid http response */
+
+       HANA_STATUS_HTTP_READ_ERROR,    /* Read error */
+       HANA_STATUS_HTTP_READ_TIMEOUT,  /* Read timeout */ 
+       HANA_STATUS_HTTP_BROKEN_PIPE,   /* Unexpected close from server */
+
+       HANA_STATUS_SIZE
+};
+
+enum {
+       HANA_ONERR_UNKNOWN      = 0,
+
+       HANA_ONERR_FASTINTER,           /* Force fastinter*/
+       HANA_ONERR_FAILCHK,             /* Simulate a failed check */
+       HANA_ONERR_SUDDTH,              /* Enters sudden death - one more 
failed check will mark this server down */
+       HANA_ONERR_MARKDWN,             /* Mark this server down, now! */
+};
+
+enum {
+       HANA_OBS_NONE           = 0,
+
+       HANA_OBS_LAYER4,                /* Observe L4 - for example tcp */
+       HANA_OBS_LAYER7,                /* Observe L7 - for example http */ 
+
+       HANA_OBS_SIZE
+};
+
 struct check_status {
        short result;                   /* one of SRV_CHK_* */
        char *info;                     /* human readable short info */
        char *desc;                     /* long description */
 };
+
+struct analyze_status {
+       char *desc;                             /* description */
+       unsigned char lr[HANA_OBS_SIZE];        /* result for l4/l7: 0 = 
ignore, 1 - error, 2 - OK */
+};
diff --git a/include/types/server.h b/include/types/server.h
index b3fe83d..a55a79e 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -115,7 +115,10 @@ struct server {
        struct sockaddr_in check_addr;          /* the address to check, if 
different from <addr> */
        short check_port;                       /* the port to use for the 
health checks */
        int health;                             /* 0->rise-1 = bad; 
rise->rise+fall-1 = good */
+       int consecutive_errors;                 /* current number of 
consecutive errors */
        int rise, fall;                         /* time in iterations */
+       int consecutive_errors_limit;           /* number of consecutive errors 
that triggers an event */
+       short observe, onerror;                 /* observing mode: one of 
HANA_OBS_*; what to do on error: on of ANA_ONERR_* */
        int inter, fastinter, downinter;        /* checks: time in milliseconds 
*/
        int slowstart;                          /* slowstart time in seconds 
(ms in the conf) */
        int result;                             /* health-check result : 
SRV_CHK_* */
@@ -137,9 +140,9 @@ struct server {
        unsigned down_time;                     /* total time the server was 
down */
        time_t last_change;                     /* last time, when the state 
was changed */
        struct timeval check_start;             /* last health check start time 
*/
-       unsigned long check_duration;           /* time in ms took to finish 
last health check */
+       long check_duration;                    /* time in ms took to finish 
last health check */
        short check_status, check_code;         /* check result, check code */
-       char check_desc[HCHK_DESC_LEN];         /* healt check descritpion */
+       char check_desc[HCHK_DESC_LEN];         /* healt check description */
 
        struct freq_ctr sess_per_sec;           /* sessions per second on this 
server */
        int puid;                               /* proxy-unique server ID, used 
for SNMP */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 428d7b9..31b367e 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2541,6 +2541,8 @@ int cfg_parse_listen(const char *file, int linenum, char 
**args, int kwm)
                newsrv->uweight = newsrv->iweight = 1;
                newsrv->maxqueue = 0;
                newsrv->slowstart = 0;
+               newsrv->onerror = DEF_HANA_ONERR;
+               newsrv->consecutive_errors_limit = DEF_HANA_ERRLIMIT;
 
                cur_arg = 3;
                while (*args[cur_arg]) {
@@ -2746,6 +2748,65 @@ int cfg_parse_listen(const char *file, int linenum, char 
**args, int kwm)
                                do_check = 1;
                                cur_arg += 1;
                        }
+                       else if (!strcmp(args[cur_arg], "observe")) {
+                               if (!strcmp(args[cur_arg + 1], "none"))
+                                       newsrv->observe = HANA_OBS_NONE;
+                               else if (!strcmp(args[cur_arg + 1], "layer4"))
+                                       newsrv->observe = HANA_OBS_LAYER4;
+                               else if (!strcmp(args[cur_arg + 1], "layer7")) {
+                                       if (curproxy->mode != PR_MODE_HTTP) {
+                                               Alert("parsing [%s:%d]: '%s' 
can only be used in http proxies.\n",
+                                                       file, linenum, 
args[cur_arg + 1]);
+                                               err_code |= ERR_ALERT;
+                                       }
+                                       newsrv->observe = HANA_OBS_LAYER7;
+                               }
+                               else {
+                                       Alert("parsing [%s:%d]: '%s' expects 
one of 'none', "
+                                               "'l4events', 'http-responses' 
but get '%s'\n",
+                                               file, linenum, args[cur_arg], 
args[cur_arg + 1]);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+                               }
+
+                               cur_arg += 2;
+                       }
+                       else if (!strcmp(args[cur_arg], "on-error")) {
+                               if (!strcmp(args[cur_arg + 1], "fastinter"))
+                                       newsrv->onerror = HANA_ONERR_FASTINTER;
+                               else if (!strcmp(args[cur_arg + 1], 
"fail-check"))
+                                       newsrv->onerror = HANA_ONERR_FAILCHK;
+                               else if (!strcmp(args[cur_arg + 1], 
"sudden-death"))
+                                       newsrv->onerror = HANA_ONERR_SUDDTH;
+                               else if (!strcmp(args[cur_arg + 1], 
"mark-down"))
+                                       newsrv->onerror = HANA_ONERR_MARKDWN;
+                               else {
+                                       Alert("parsing [%s:%d]: '%s' expects 
one of 'fastinter', "
+                                               "'fail-check', 'sudden-death' 
or 'mark-down' but get '%s'\n",
+                                               file, linenum, args[cur_arg], 
args[cur_arg + 1]);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+                               }
+
+                               cur_arg += 2;
+                       }
+                       else if (!strcmp(args[cur_arg], "error_limit")) {
+                               if (!*args[cur_arg + 1]) {
+                                       Alert("parsing [%s:%d]: '%s' expects an 
integer argument.\n",
+                                               file, linenum, args[cur_arg]);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+                               }
+
+                               newsrv->consecutive_errors_limit = 
atoi(args[cur_arg + 1]);
+
+                               if (newsrv->consecutive_errors_limit <= 0) {
+                                       Alert("parsing [%s:%d]: %s has to be > 
0.\n",
+                                               file, linenum, args[cur_arg]);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+                               }
+                       }
                        else if (!strcmp(args[cur_arg], "source")) {  /* 
address to which we bind when connecting */
                                int port_low, port_high;
                                if (!*args[cur_arg + 1]) {
diff --git a/src/checks.c b/src/checks.c
index 0e9aca5..3bfd791 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -52,6 +52,8 @@ const struct check_status check_statuses[HCHK_STATUS_SIZE] = {
        [HCHK_STATUS_INI]       = { SRV_CHK_UNKNOWN,                   "INI",   
  "Initializing" },
        [HCHK_STATUS_START]     = { /* SPECIAL STATUS*/ },
 
+       [HCHK_STATUS_HANA]      = { SRV_CHK_ERROR,                     "HANA",  
  "Health analyze" },
+
        [HCHK_STATUS_SOCKERR]   = { SRV_CHK_ERROR,                     
"SOCKERR", "Socket error" },
 
        [HCHK_STATUS_L4OK]      = { SRV_CHK_RUNNING,                   "L4OK",  
  "Layer4 check passed" },
@@ -72,6 +74,22 @@ const struct check_status check_statuses[HCHK_STATUS_SIZE] = 
{
        [HCHK_STATUS_L7STS]     = { SRV_CHK_ERROR,                     "L7STS", 
  "Layer7 wrong status" },
 };
 
+const struct analyze_status analyze_statuses[HANA_STATUS_SIZE] = {             
/* 0: ignore, 1: error, 2: OK */
+       [HANA_STATUS_UNKNOWN]           = { "Unknown",                         
{ 0, 0 }},
+
+       [HANA_STATUS_L4_OK]             = { "L4 successful connection",        
{ 2, 0 }},
+       [HANA_STATUS_L4_ERR]            = { "L4 unsuccessful connection",      
{ 1, 1 }},
+
+       [HANA_STATUS_HTTP_OK]           = { "Correct http response",           
{ 0, 2 }},
+       [HANA_STATUS_HTTP_STS]          = { "Wrong http response",             
{ 0, 1 }},
+       [HANA_STATUS_HTTP_HDRRSP]       = { "Invalid http response (headers)", 
{ 0, 1 }},
+       [HANA_STATUS_HTTP_RSP]          = { "Invalid http response",           
{ 0, 1 }},
+
+       [HANA_STATUS_HTTP_READ_ERROR]   = { "Read error (http)",               
{ 0, 1 }},
+       [HANA_STATUS_HTTP_READ_TIMEOUT] = { "Read timeout (http)",             
{ 0, 1 }},
+       [HANA_STATUS_HTTP_BROKEN_PIPE]  = { "Close from server (http)",        
{ 0, 1 }},
+};
+
 /*
  * Convert check_status code to description
  */
@@ -108,6 +126,21 @@ const char *get_check_status_info(short check_status) {
                return check_statuses[HCHK_STATUS_UNKNOWN].info;
 }
 
+const char *get_analyze_status(short analyze_status) {
+
+       const char *desc;
+
+       if (analyze_status < HANA_STATUS_SIZE)
+               desc = analyze_statuses[analyze_status].desc;
+       else
+               desc = NULL;
+
+       if (desc && *desc)
+               return desc;
+       else
+               return analyze_statuses[HANA_STATUS_UNKNOWN].desc;
+}
+
 #define SSP_O_VIA      0x0001
 #define SSP_O_HCHK     0x0002
 #define SSP_O_STATUS   0x0004
@@ -136,7 +169,8 @@ static void server_status_printf(struct chunk *msg, struct 
server *s, unsigned o
                        chunk_printf(msg, "\"");
                }
 
-               chunk_printf(msg, ", check duration: %lums", s->check_duration);
+               if (s->check_duration >= 0)
+                       chunk_printf(msg, ", check duration: %ldms", 
s->check_duration);
        }
 
        if (options & SSP_O_STATUS) {
@@ -184,9 +218,11 @@ static void set_server_check_status(struct server *s, 
short status, char *desc)
 
        s->check_status = status;
        if (check_statuses[status].result)
-               s->result |= check_statuses[status].result;
+               s->result = check_statuses[status].result;
 
-       if (!tv_iszero(&s->check_start)) {
+       if (status == HCHK_STATUS_HANA)
+               s->check_duration = -1;
+       else if (!tv_iszero(&s->check_start)) {
                /* set_server_check_status() may be called more than once */
                s->check_duration = tv_ms_elapsed(&s->check_start, &now);
                tv_zero(&s->check_start);
@@ -229,6 +265,10 @@ static void set_server_check_status(struct server *s, 
short status, char *desc)
                                if (health >= rise)
                                        health = rise + fall - 1; /* OK now */
                        }
+
+                       /* clear consecutive_errors if observing is enabled */
+                       if (s->onerror)
+                               s->consecutive_errors = 0;
                }
                /* FIXME end: calculate local version of the 
health/rise/fall/state */
 
@@ -505,6 +545,95 @@ static void set_server_enabled(struct server *s) {
                        set_server_enabled(srv);
 }
 
+void health_adjust(struct server *s, short status) {
+
+       int failed;
+       int expire;
+
+       /* return now if observing nor healt check is not enabled */
+       if (!s->observe || !s->check)
+               return;
+
+       if (s->observe >= HANA_OBS_SIZE)
+               return;
+
+       if (status >= HCHK_STATUS_SIZE || !analyze_statuses[status].desc)
+               return;
+
+       switch (analyze_statuses[status].lr[s->observe - 1]) {
+               case 1:
+                       failed = 1;
+                       break;
+
+               case 2:
+                       failed = 0;
+                       break;
+
+               default:
+                       return;
+       }
+
+       if (!failed) {
+               /* good: clear consecutive_errors */
+               s->consecutive_errors = 0;
+               return;
+       }
+
+       s->consecutive_errors++;
+
+       if (s->consecutive_errors < s->consecutive_errors_limit)
+               return;
+
+       sprintf(trash, "Detected %d consecutive errors, last one was: %s",
+               s->consecutive_errors, get_analyze_status(status));
+
+       switch (s->onerror) {
+               case HANA_ONERR_FASTINTER:
+               /* force fastinter - nothing to do here as all modes force it */
+                       break;
+
+               case HANA_ONERR_SUDDTH:
+               /* simulate a pre-fatal failed health check */
+                       if (s->health > s->rise)
+                               s->health = s->rise + 1;
+
+                       /* no break - fall through */
+
+               case HANA_ONERR_FAILCHK:
+               /* simulate a failed health check */
+                       set_server_check_status(s, HCHK_STATUS_HANA, trash);
+
+                       if (s->health > s->rise) {
+                               s->health--; /* still good */
+                               s->counters.failed_checks++;
+                       }
+                       else
+                               set_server_down(s);
+
+                       break;
+
+               case HANA_ONERR_MARKDWN:
+               /* mark server down */
+                       s->health = s->rise;
+                       set_server_check_status(s, HCHK_STATUS_HANA, trash);
+                       set_server_down(s);
+
+                       break;
+
+               default:
+                       /* write a warning? */
+                       break;
+       }
+
+       s->consecutive_errors = 0;
+
+       if (s->fastinter) {
+               expire = tick_add(now_ms, MS_TO_TICKS(s->fastinter));
+               if (s->check->expire > expire)
+                       s->check->expire = expire;
+       }
+}
+
 /*
  * This function is used only for server health-checks. It handles
  * the connection acknowledgement. If the proxy requires L7 health-checks,
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 522c3f8..d23602a 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -1545,7 +1545,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, 
struct uri_auth *uri)
                                        if (sv->check_status >= 
HCHK_STATUS_L57DATA)
                                                chunk_printf(&msg, "/%d", 
sv->check_code);
 
-                                       if (sv->check_status >= 
HCHK_STATUS_CHECKED)
+                                       if (sv->check_status >= 
HCHK_STATUS_CHECKED && sv->check_duration >= 0)
                                                chunk_printf(&msg, " in %lums", 
sv->check_duration);
                                } else {
                                        chunk_printf(&msg, "</td><td>");
diff --git a/src/proto_http.c b/src/proto_http.c
index 2300738..408066b 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -41,6 +41,7 @@
 #include <proto/acl.h>
 #include <proto/backend.h>
 #include <proto/buffers.h>
+#include <proto/checks.h>
 #include <proto/client.h>
 #include <proto/dumpstats.h>
 #include <proto/fd.h>
@@ -2857,8 +2858,10 @@ int process_response(struct session *t)
 
                                buffer_shutr_now(rep);
                                buffer_shutw_now(req);
-                               if (t->srv)
+                               if (t->srv) {
                                        t->srv->counters.failed_resp++;
+                                       health_adjust(t->srv, 
HANA_STATUS_HTTP_HDRRSP);
+                               }
                                t->be->counters.failed_resp++;
                                rep->analysers = 0;
                                txn->status = 502;
@@ -2880,8 +2883,10 @@ int process_response(struct session *t)
                                        
http_capture_bad_message(&t->be->invalid_rep, t, rep, msg, t->fe);
                                buffer_shutr_now(rep);
                                buffer_shutw_now(req);
-                               if (t->srv)
+                               if (t->srv) {
                                        t->srv->counters.failed_resp++;
+                                       health_adjust(t->srv, 
HANA_STATUS_HTTP_READ_ERROR);
+                               }
                                t->be->counters.failed_resp++;
                                rep->analysers = 0;
                                txn->status = 502;
@@ -2898,8 +2903,10 @@ int process_response(struct session *t)
                                        
http_capture_bad_message(&t->be->invalid_rep, t, rep, msg, t->fe);
                                buffer_shutr_now(rep);
                                buffer_shutw_now(req);
-                               if (t->srv)
+                               if (t->srv) {
                                        t->srv->counters.failed_resp++;
+                                       health_adjust(t->srv, 
HANA_STATUS_HTTP_READ_TIMEOUT);
+                               }
                                t->be->counters.failed_resp++;
                                rep->analysers = 0;
                                txn->status = 504;
@@ -2915,8 +2922,10 @@ int process_response(struct session *t)
                                if (msg->err_pos >= 0)
                                        
http_capture_bad_message(&t->be->invalid_rep, t, rep, msg, t->fe);
                                buffer_shutw_now(req);
-                               if (t->srv)
+                               if (t->srv) {
                                        t->srv->counters.failed_resp++;
+                                       health_adjust(t->srv, 
HANA_STATUS_HTTP_BROKEN_PIPE);
+                               }
                                t->be->counters.failed_resp++;
                                rep->analysers = 0;
                                txn->status = 502;
@@ -2971,6 +2980,11 @@ int process_response(struct session *t)
                if (n < 1 || n > 5)
                        n = 0;
 
+               if (txn->status >= 100 && txn->status < 500)
+                       health_adjust(t->srv, HANA_STATUS_HTTP_OK);
+               else
+                       health_adjust(t->srv, HANA_STATUS_HTTP_STS);
+
                t->srv->counters.p.http.rsp[n]++;
                t->be->counters.p.http.rsp[n]++;
 
@@ -3027,8 +3041,10 @@ int process_response(struct session *t)
                        if (rule_set->rsp_exp != NULL) {
                                if (apply_filters_to_response(t, rep, 
rule_set->rsp_exp) < 0) {
                                return_bad_resp:
-                                       if (t->srv)
+                                       if (t->srv) {
                                                t->srv->counters.failed_resp++;
+                                               health_adjust(t->srv, 
HANA_STATUS_HTTP_RSP);
+                                       }
                                        cur_proxy->counters.failed_resp++;
                                return_srv_prx_502:
                                        buffer_shutr_now(rep);
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 7bb5d7e..6f7c6d6 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -43,6 +43,7 @@
 #include <proto/acl.h>
 #include <proto/backend.h>
 #include <proto/buffers.h>
+#include <proto/checks.h>
 #include <proto/fd.h>
 #include <proto/log.h>
 #include <proto/port_range.h>
diff --git a/src/session.c b/src/session.c
index 447660e..da99703 100644
--- a/src/session.c
+++ b/src/session.c
@@ -246,6 +246,8 @@ int sess_update_st_cer(struct session *s, struct 
stream_interface *si)
 {
        /* we probably have to release last session from the server */
        if (s->srv) {
+               health_adjust(s->srv, HANA_STATUS_L4_ERR);
+
                if (s->flags & SN_CURR_SESS) {
                        s->flags &= ~SN_CURR_SESS;
                        s->srv->cur_sess--;
@@ -324,6 +326,9 @@ void sess_establish(struct session *s, struct 
stream_interface *si)
        struct buffer *req = si->ob;
        struct buffer *rep = si->ib;
 
+       if (s->srv)
+               health_adjust(s->srv, HANA_STATUS_L4_OK);
+
        if (s->be->mode == PR_MODE_TCP) { /* let's allow immediate data 
connection in this case */
                buffer_set_rlim(rep, rep->size); /* no rewrite needed */
 

Reply via email to