]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] checks: group health checks methods by values and save option bits
authorWilly Tarreau <w@1wt.eu>
Sat, 6 Aug 2011 15:05:02 +0000 (17:05 +0200)
committerWilly Tarreau <w@1wt.eu>
Sat, 6 Aug 2011 15:08:40 +0000 (17:08 +0200)
Adding health checks has become a real pain, with cross-references to all
checks everywhere because they're all a single bit. Since they're all
exclusive, let's change this to have a check number only. We reserve 4
bits allowing up to 16 checks (15+tcp), only 7 of which are currently
used. The code has shrunk by almost 1kB and we saved a few option bits.

The "dispatch" option has been moved to px->options, making a few tests
a bit cleaner.

include/types/proxy.h
src/backend.c
src/cfgparse.c
src/checks.c
src/frontend.c

index b4385a9854012fac23b59141690a75a16c0c7cea..e4fcc7750d2abc1b3df7e66fe5b9e62192f362a2 100644 (file)
@@ -78,14 +78,14 @@ enum {
 #define PR_O_COOK_INS   0x00000010      /* insert cookies when not accessing a server directly */
 #define PR_O_COOK_PFX   0x00000020      /* rewrite all cookies by prefixing the right serverid */
 #define PR_O_COOK_ANY   (PR_O_COOK_RW | PR_O_COOK_IND | PR_O_COOK_INS | PR_O_COOK_PFX)
-#define PR_O_SMTP_CHK   0x00000040      /* use SMTP EHLO check for server health - pvandijk@vision6.com.au */
+#define PR_O_DISPATCH   0x00000040      /* use dispatch mode */
 #define PR_O_KEEPALIVE  0x00000080      /* follow keep-alive sessions */
 #define PR_O_FWDFOR     0x00000100      /* insert x-forwarded-for with client address */
 #define PR_O_BIND_SRC   0x00000200      /* bind to a specific source address when connect()ing */
 #define PR_O_NULLNOLOG  0x00000400      /* a connect without request will not be logged */
 #define PR_O_COOK_NOC   0x00000800      /* add a 'Cache-control' header with the cookie */
 #define PR_O_COOK_POST  0x00001000      /* don't insert cookies for requests other than a POST */
-#define PR_O_HTTP_CHK   0x00002000      /* use HTTP 'OPTIONS' method to check server health */
+/* unused: 0x00002000 */
 #define PR_O_PERSIST    0x00004000      /* server persistence stays effective even when server is down */
 #define PR_O_LOGASAP    0x00008000      /* log as soon as possible, without waiting for the session to complete */
 #define PR_O_HTTP_CLOSE 0x00010000      /* force 'connection: close' in both directions */
@@ -135,14 +135,12 @@ enum {
 #define PR_O2_AS_M_PP  0x00000000      /* path-parameters mode (the default mode) */
 #define PR_O2_AS_M_QS  0x00010000      /* query-string mode */
 #define PR_O2_AS_M_ANY 0x00010000      /* mask covering all PR_O2_AS_M_* values */
-
-#define PR_O2_MYSQL_CHK 0x00020000      /* use MYSQL check for server health */
+#define PR_O2_NODELAY   0x00020000      /* fully interactive mode, never delay outgoing data */
 #define PR_O2_USE_PXHDR 0x00040000      /* use Proxy-Connection for proxy requests */
 #define PR_O2_CHK_SNDST 0x00080000      /* send the state of each server along with HTTP health checks */
-#define PR_O2_SSL3_CHK  0x00100000      /* use SSLv3 CLIENT_HELLO packets for server health */
+/* unused: 0x00100000 */
 #define PR_O2_FAKE_KA   0x00200000      /* pretend we do keep-alive with server eventhough we close */
-#define PR_O2_LDAP_CHK  0x00400000      /* use LDAP check for server health */
-
+/* unused: 0x00400000 */
 #define PR_O2_EXP_NONE  0x00000000      /* http-check : no expect rule */
 #define PR_O2_EXP_STS   0x00800000      /* http-check expect status */
 #define PR_O2_EXP_RSTS  0x01000000      /* http-check expect rstatus */
@@ -152,10 +150,17 @@ enum {
 #define PR_O2_EXP_INV   0x04000000      /* http-check expect !<rule> */
 #define PR_O2_COOK_PSV  0x08000000      /* cookie ... preserve */
 
+/* server health checks */
+#define PR_O2_CHK_NONE  0x00000000      /* no L7 health checks configured (TCP by default) */
 #define PR_O2_PGSQL_CHK 0x10000000      /* use PGSQL check for server health */
-#define PR_O2_DISPATCH  0x20000000      /* use dispatch mode */
-#define PR_O2_NODELAY   0x40000000      /* fully interactive mode, never delay outgoing data */
-#define PR_O2_REDIS_CHK 0x80000000      /* use LDAP check for server health */
+#define PR_O2_REDIS_CHK 0x20000000      /* use LDAP check for server health */
+#define PR_O2_SMTP_CHK  0x30000000      /* use SMTP EHLO check for server health - pvandijk@vision6.com.au */
+#define PR_O2_HTTP_CHK  0x40000000      /* use HTTP 'OPTIONS' method to check server health */
+#define PR_O2_MYSQL_CHK 0x50000000      /* use MYSQL check for server health */
+#define PR_O2_LDAP_CHK  0x60000000      /* use LDAP check for server health */
+#define PR_O2_SSL3_CHK  0x70000000      /* use SSLv3 CLIENT_HELLO packets for server health */
+/* unused: 0x80000000 to 0xF000000, reserved for health checks */
+#define PR_O2_CHK_ANY   0xF0000000      /* Mask to cover any check */
 /* end of proxy->options2 */
 
 /* bits for sticking rules */
index d76324fc5446151b832c27391822adcfb165dad8..2cbc8880cb864f35260381187f7650b2831eb9d4 100644 (file)
@@ -618,7 +618,7 @@ int assign_server(struct session *s)
                }
                set_target_server(&s->target, srv);
        }
-       else if ((s->be->options2 & PR_O2_DISPATCH) || (s->be->options & PR_O_TRANSP)) {
+       else if (s->be->options & (PR_O_DISPATCH | PR_O_TRANSP)) {
                set_target_proxy(&s->target, s->be);
        }
        else if ((s->be->options & PR_O_HTTP_PROXY) &&
@@ -720,7 +720,7 @@ int assign_server_address(struct session *s)
                        }
                }
        }
-       else if (s->be->options2 & PR_O2_DISPATCH) {
+       else if (s->be->options & PR_O_DISPATCH) {
                /* connect to the defined dispatch addr */
                s->req->cons->addr.s.to = s->be->dispatch_addr;
        }
index 44fc1dabd96e20e40224de786deb98494a4b1e33..8c61f3d5353f993b03b8f7aca76fd8e93b123adb 100644 (file)
@@ -3255,13 +3255,8 @@ stats_error_parsing:
                        /* use HTTP request to check servers' health */
                        free(curproxy->check_req);
                        curproxy->check_req = NULL;
-                       curproxy->options &= ~PR_O_SMTP_CHK;
-                       curproxy->options2 &= ~PR_O2_SSL3_CHK;
-                       curproxy->options2 &= ~PR_O2_MYSQL_CHK;
-                       curproxy->options2 &= ~PR_O2_PGSQL_CHK;
-                       curproxy->options2 &= ~PR_O2_LDAP_CHK;
-                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
-                       curproxy->options |= PR_O_HTTP_CHK;
+                       curproxy->options2 &= ~PR_O2_CHK_ANY;
+                       curproxy->options2 |= PR_O2_HTTP_CHK;
                        if (!*args[2]) { /* no argument */
                                curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
                                curproxy->check_len = strlen(DEF_CHECK_REQ);
@@ -3289,25 +3284,15 @@ stats_error_parsing:
 
                        free(curproxy->check_req);
                        curproxy->check_req = NULL;
-                       curproxy->options &= ~PR_O_HTTP_CHK;
-                       curproxy->options &= ~PR_O_SMTP_CHK;
-                       curproxy->options2 &= ~PR_O2_MYSQL_CHK;
-                       curproxy->options2 &= ~PR_O2_PGSQL_CHK;
-                       curproxy->options2 &= ~PR_O2_LDAP_CHK;
-                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
+                       curproxy->options2 &= ~PR_O2_CHK_ANY;
                        curproxy->options2 |= PR_O2_SSL3_CHK;
                }
                else if (!strcmp(args[1], "smtpchk")) {
                        /* use SMTP request to check servers' health */
                        free(curproxy->check_req);
                        curproxy->check_req = NULL;
-                       curproxy->options &= ~PR_O_HTTP_CHK;
-                       curproxy->options2 &= ~PR_O2_SSL3_CHK;
-                       curproxy->options2 &= ~PR_O2_MYSQL_CHK;
-                       curproxy->options2 &= ~PR_O2_PGSQL_CHK;
-                       curproxy->options2 &= ~PR_O2_LDAP_CHK;
-                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
-                       curproxy->options |= PR_O_SMTP_CHK;
+                       curproxy->options2 &= ~PR_O2_CHK_ANY;
+                       curproxy->options2 |= PR_O2_SMTP_CHK;
 
                        if (!*args[2] || !*args[3]) { /* no argument or incomplete EHLO host */
                                curproxy->check_req = strdup(DEF_SMTP_CHECK_REQ); /* default request */
@@ -3333,12 +3318,7 @@ stats_error_parsing:
 
                        free(curproxy->check_req);
                        curproxy->check_req = NULL;
-                       curproxy->options &= ~PR_O_HTTP_CHK;
-                       curproxy->options &= ~PR_O_SMTP_CHK;
-                       curproxy->options2 &= ~PR_O2_SSL3_CHK;
-                       curproxy->options2 &= ~PR_O2_LDAP_CHK;
-                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
-                       curproxy->options2 &= ~PR_O2_MYSQL_CHK;
+                       curproxy->options2 &= ~PR_O2_CHK_ANY;
                        curproxy->options2 |= PR_O2_PGSQL_CHK;
 
                        if (*(args[2])) {
@@ -3397,12 +3377,7 @@ stats_error_parsing:
 
                        free(curproxy->check_req);
                        curproxy->check_req = NULL;
-                       curproxy->options &= ~PR_O_HTTP_CHK;
-                       curproxy->options &= ~PR_O_SMTP_CHK;
-                       curproxy->options2 &= ~PR_O2_SSL3_CHK;
-                       curproxy->options2 &= ~PR_O2_MYSQL_CHK;
-                       curproxy->options2 &= ~PR_O2_PGSQL_CHK;
-                       curproxy->options2 &= ~PR_O2_LDAP_CHK;
+                       curproxy->options2 &= ~PR_O2_CHK_ANY;
                        curproxy->options2 |= PR_O2_REDIS_CHK;
 
                        curproxy->check_req = (char *) malloc(sizeof(DEF_REDIS_CHECK_REQ) - 1);
@@ -3417,12 +3392,7 @@ stats_error_parsing:
 
                        free(curproxy->check_req);
                        curproxy->check_req = NULL;
-                       curproxy->options &= ~PR_O_HTTP_CHK;
-                       curproxy->options &= ~PR_O_SMTP_CHK;
-                       curproxy->options2 &= ~PR_O2_SSL3_CHK;
-                       curproxy->options2 &= ~PR_O2_LDAP_CHK;
-                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
-                       curproxy->options2 &= ~PR_O2_PGSQL_CHK;
+                       curproxy->options2 &= ~PR_O2_CHK_ANY;
                        curproxy->options2 |= PR_O2_MYSQL_CHK;
 
                        /* This is an exemple of an MySQL >=4.0 client Authentication packet kindly provided by Cyril Bonte.
@@ -3489,12 +3459,7 @@ stats_error_parsing:
                        /* use LDAP request to check servers' health */
                        free(curproxy->check_req);
                        curproxy->check_req = NULL;
-                       curproxy->options &= ~PR_O_HTTP_CHK;
-                       curproxy->options &= ~PR_O_SMTP_CHK;
-                       curproxy->options2 &= ~PR_O2_SSL3_CHK;
-                       curproxy->options2 &= ~PR_O2_MYSQL_CHK;
-                       curproxy->options2 &= ~PR_O2_PGSQL_CHK;
-                       curproxy->options2 &= ~PR_O2_REDIS_CHK;
+                       curproxy->options2 &= ~PR_O2_CHK_ANY;
                        curproxy->options2 |= PR_O2_LDAP_CHK;
 
                        curproxy->check_req = (char *) malloc(sizeof(DEF_LDAP_CHECK_REQ) - 1);
@@ -3836,7 +3801,7 @@ stats_error_parsing:
                        goto out;
                }
                curproxy->dispatch_addr = *sk;
-               curproxy->options2 |= PR_O2_DISPATCH;
+               curproxy->options |= PR_O_DISPATCH;
        }
        else if (!strcmp(args[0], "balance")) {  /* set balancing with optional algorithm */
                if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
@@ -5619,14 +5584,13 @@ int check_config_validity()
                                        cfgerr++;
                                }
 #endif
-                               else if (curproxy->options2 & PR_O2_DISPATCH) {
+                               else if (curproxy->options & PR_O_DISPATCH) {
                                        Warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
                                                proxy_type_str(curproxy), curproxy->id);
                                        err_code |= ERR_WARN;
                                }
                        }
-                       else if (!(curproxy->options & (PR_O_TRANSP | PR_O_HTTP_PROXY)) &&
-                                !(curproxy->options2 & PR_O2_DISPATCH)) {
+                       else if (!(curproxy->options & (PR_O_TRANSP | PR_O_DISPATCH | PR_O_HTTP_PROXY))) {
                                /* If no LB algo is set in a backend, and we're not in
                                 * transparent mode, dispatch mode nor proxy mode, we
                                 * want to use balance roundrobin by default.
@@ -5636,31 +5600,26 @@ int check_config_validity()
                        }
                }
 
-               if (curproxy->options2 & PR_O2_DISPATCH) {
-                       curproxy->options  &= ~PR_O_TRANSP;
-                       curproxy->options  &= ~PR_O_HTTP_PROXY;
-               }
-               else if (curproxy->options & PR_O_HTTP_PROXY) {
-                       curproxy->options2 &= ~PR_O2_DISPATCH;
-                       curproxy->options  &= ~PR_O_TRANSP;
-               }
-               else if (curproxy->options & PR_O_TRANSP) {
-                       curproxy->options2 &= ~PR_O2_DISPATCH;
-                       curproxy->options  &= ~PR_O_HTTP_PROXY;
-               }
-
-               if ((curproxy->options & PR_O_DISABLE404) && !(curproxy->options & PR_O_HTTP_CHK)) {
-                       curproxy->options &= ~PR_O_DISABLE404;
-                       Warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
-                               "disable-on-404", proxy_type_str(curproxy), curproxy->id);
-                       err_code |= ERR_WARN;
-               }
+               if (curproxy->options & PR_O_DISPATCH)
+                       curproxy->options &= ~(PR_O_TRANSP | PR_O_HTTP_PROXY);
+               else if (curproxy->options & PR_O_HTTP_PROXY)
+                       curproxy->options &= ~(PR_O_DISPATCH | PR_O_TRANSP);
+               else if (curproxy->options & PR_O_TRANSP)
+                       curproxy->options &= ~(PR_O_DISPATCH | PR_O_HTTP_PROXY);
 
-               if ((curproxy->options2 & PR_O2_CHK_SNDST) && !(curproxy->options & PR_O_HTTP_CHK)) {
-                       curproxy->options &= ~PR_O2_CHK_SNDST;
-                       Warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
-                               "send-state", proxy_type_str(curproxy), curproxy->id);
-                       err_code |= ERR_WARN;
+               if ((curproxy->options2 & PR_O2_CHK_ANY) != PR_O2_HTTP_CHK) {
+                       if (curproxy->options & PR_O_DISABLE404) {
+                               Warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
+                                       "disable-on-404", proxy_type_str(curproxy), curproxy->id);
+                               err_code |= ERR_WARN;
+                               curproxy->options &= ~PR_O_DISABLE404;
+                       }
+                       if (curproxy->options2 & PR_O2_CHK_SNDST) {
+                               Warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
+                                       "send-state", proxy_type_str(curproxy), curproxy->id);
+                               err_code |= ERR_WARN;
+                               curproxy->options &= ~PR_O2_CHK_SNDST;
+                       }
                }
 
                /* if a default backend was specified, let's find it */
@@ -6001,7 +5960,7 @@ out_uri_auth_compat:
                        }
                }
 
-               if (curproxy->options2 & PR_O2_SSL3_CHK) {
+               if ((curproxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
                        curproxy->check_len = sizeof(sslv3_client_hello_pkt) - 1;
                        curproxy->check_req = (char *)malloc(curproxy->check_len);
                        memcpy(curproxy->check_req, sslv3_client_hello_pkt, curproxy->check_len);
index 50fe2a2048daf487b5e7647fba3b8719040bcfdb..2e22b49e339e084ce7252dd41266cf8f6350a054 100644 (file)
@@ -768,13 +768,7 @@ static int event_srv_chk_w(int fd)
 
        if (!(s->result & SRV_CHK_ERROR)) {
                /* we don't want to mark 'UP' a server on which we detected an error earlier */
-               if ((s->proxy->options & PR_O_HTTP_CHK) ||
-                   (s->proxy->options & PR_O_SMTP_CHK) ||
-                   (s->proxy->options2 & PR_O2_SSL3_CHK) ||
-                   (s->proxy->options2 & PR_O2_MYSQL_CHK) ||
-                   (s->proxy->options2 & PR_O2_PGSQL_CHK) ||
-                   (s->proxy->options2 & PR_O2_REDIS_CHK) ||
-                   (s->proxy->options2 & PR_O2_LDAP_CHK)) {
+               if (s->proxy->options2 & PR_O2_CHK_ANY) {
                        int ret;
                        const char *check_req = s->proxy->check_req;
                        int check_len = s->proxy->check_len;
@@ -783,12 +777,12 @@ static int event_srv_chk_w(int fd)
                         * so we'll send the request, and won't wake the checker up now.
                         */
 
-                       if (s->proxy->options2 & PR_O2_SSL3_CHK) {
+                       if ((s->proxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK) {
                                /* SSL requires that we put Unix time in the request */
                                int gmt_time = htonl(date.tv_sec);
                                memcpy(s->proxy->check_req + 11, &gmt_time, 4);
                        }
-                       else if (s->proxy->options & PR_O_HTTP_CHK) {
+                       else if ((s->proxy->options2 & PR_O2_CHK_ANY) == PR_O2_HTTP_CHK) {
                                memcpy(trash, check_req, check_len);
 
                                if (s->proxy->options2 & PR_O2_CHK_SNDST)
@@ -956,7 +950,8 @@ static int event_srv_chk_r(int fd)
        }
 
        /* Run the checks... */
-       if (s->proxy->options & PR_O_HTTP_CHK) {
+       switch (s->proxy->options2 & PR_O2_CHK_ANY) {
+       case PR_O2_HTTP_CHK:
                if (!done && s->check_data_len < strlen("HTTP/1.0 000\r"))
                        goto wait_more_data;
 
@@ -995,8 +990,9 @@ static int event_srv_chk_r(int fd)
                        cut_crlf(desc);
                        set_server_check_status(s, HCHK_STATUS_L7STS, desc);
                }
-       }
-       else if (s->proxy->options2 & PR_O2_SSL3_CHK) {
+               break;
+
+       case PR_O2_SSL3_CHK:
                if (!done && s->check_data_len < 5)
                        goto wait_more_data;
 
@@ -1005,8 +1001,9 @@ static int event_srv_chk_r(int fd)
                        set_server_check_status(s, HCHK_STATUS_L6OK, NULL);
                else
                        set_server_check_status(s, HCHK_STATUS_L6RSP, NULL);
-       }
-       else if (s->proxy->options & PR_O_SMTP_CHK) {
+               break;
+
+       case PR_O2_SMTP_CHK:
                if (!done && s->check_data_len < strlen("000\r"))
                        goto wait_more_data;
 
@@ -1031,8 +1028,9 @@ static int event_srv_chk_r(int fd)
                        set_server_check_status(s, HCHK_STATUS_L7OKD, desc);
                else
                        set_server_check_status(s, HCHK_STATUS_L7STS, desc);
-       }
-       else if (s->proxy->options2 & PR_O2_PGSQL_CHK) {
+               break;
+
+       case PR_O2_PGSQL_CHK:
                if (!done && s->check_data_len < 9)
                        goto wait_more_data;
 
@@ -1047,8 +1045,9 @@ static int event_srv_chk_r(int fd)
 
                        set_server_check_status(s, HCHK_STATUS_L7STS, desc);
                }
-       }
-       else if (s->proxy->options2 & PR_O2_REDIS_CHK) {
+               break;
+
+       case PR_O2_REDIS_CHK:
                if (!done && s->check_data_len < 7)
                        goto wait_more_data;
 
@@ -1058,8 +1057,9 @@ static int event_srv_chk_r(int fd)
                else {
                        set_server_check_status(s, HCHK_STATUS_L7STS, s->check_data);
                }
-       }
-       else if (s->proxy->options2 & PR_O2_MYSQL_CHK) {
+               break;
+
+       case PR_O2_MYSQL_CHK:
                if (!done && s->check_data_len < 5)
                        goto wait_more_data;
 
@@ -1145,8 +1145,9 @@ static int event_srv_chk_r(int fd)
                                set_server_check_status(s, HCHK_STATUS_L7RSP, desc);
                        }
                }
-       }
-       else if (s->proxy->options2 & PR_O2_LDAP_CHK) {
+               break;
+
+       case PR_O2_LDAP_CHK:
                if (!done && s->check_data_len < 14)
                        goto wait_more_data;
 
@@ -1199,11 +1200,13 @@ static int event_srv_chk_r(int fd)
                                set_server_check_status(s, HCHK_STATUS_L7OKD, "Success");
                        }
                }
-       }
-       else {
+               break;
+
+       default:
                /* other checks are valid if the connection succeeded anyway */
                set_server_check_status(s, HCHK_STATUS_L4OK, NULL);
-       }
+               break;
+       } /* switch */
 
  out_wakeup:
        if (s->result & SRV_CHK_ERROR)
@@ -1552,7 +1555,7 @@ struct task *process_chk(struct task *t)
                                if (!EV_FD_ISSET(fd, DIR_RD)) {
                                        set_server_check_status(s, HCHK_STATUS_L4TOUT, NULL);
                                } else {
-                                       if (s->proxy->options2 & PR_O2_SSL3_CHK)
+                                       if ((s->proxy->options2 & PR_O2_CHK_ANY) == PR_O2_SSL3_CHK)
                                                set_server_check_status(s, HCHK_STATUS_L6TOUT, NULL);
                                        else    /* HTTP, SMTP */
                                                set_server_check_status(s, HCHK_STATUS_L7TOUT, NULL);
index 558bb9ec1d98fa5e3753f4f135725de6fbb999ea..b2bc5d8a7b74bc64f7425f5976f3efb7fa98d16e 100644 (file)
@@ -243,7 +243,7 @@ int frontend_accept(struct session *s)
                fdtab[cfd].flags |= FD_FL_TCP_NOLING;
 
        if (unlikely((s->fe->mode == PR_MODE_HTTP && (s->flags & SN_MONITOR)) ||
-                    (s->fe->mode == PR_MODE_HEALTH && (s->fe->options & PR_O_HTTP_CHK)))) {
+                    (s->fe->mode == PR_MODE_HEALTH && ((s->fe->options2 & PR_O2_CHK_ANY) == PR_O2_HTTP_CHK)))) {
                /* Either we got a request from a monitoring system on an HTTP instance,
                 * or we're in health check mode with the 'httpchk' option enabled. In
                 * both cases, we return a fake "HTTP/1.0 200 OK" response and we exit.