[MEDIUM] checks: group health checks methods by values and save option bits

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.
diff --git a/src/backend.c b/src/backend.c
index d76324f..2cbc888 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -618,7 +618,7 @@
 		}
 		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 @@
 			}
 		}
 	}
-	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;
 	}
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 44fc1da..8c61f3d 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -3255,13 +3255,8 @@
 			/* 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 @@
 
 			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 @@
 
 			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 @@
 
 			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 @@
 
 			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 @@
 			/* 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 @@
 			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 @@
 					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 @@
 			}
 		}
 
-		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 @@
 			}
 		}
 
-		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);
diff --git a/src/checks.c b/src/checks.c
index 50fe2a2..2e22b49 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -768,13 +768,7 @@
 
 	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 @@
 			 * 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 @@
 	}
 
 	/* 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 @@
 			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 @@
 			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 @@
 			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 @@
 
 			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 @@
 		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 @@
 				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 @@
 				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 @@
 				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);
diff --git a/src/frontend.c b/src/frontend.c
index 558bb9e..b2bc5d8 100644
--- a/src/frontend.c
+++ b/src/frontend.c
@@ -243,7 +243,7 @@
 		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.