MEDIUM: checks: add send/expect tcp based check

This is a generic health check which can be used to match a
banner or send a request and analyse a server response.
It works in a send/expect ways and many exchange can be done between
HAProxy and a server to decide the server status, making HAProxy able to
speak the server's protocol.

It can send arbitrary regular or binary strings and match content as a
regular or binary string or a regex.

Signed-off-by: Baptiste Assmann <bedis9@gmail.com>
diff --git a/include/types/checks.h b/include/types/checks.h
index 09a4eee..d7d9725 100644
--- a/include/types/checks.h
+++ b/include/types/checks.h
@@ -106,4 +106,21 @@
 	unsigned char lr[HANA_OBS_SIZE];	/* result for l4/l7: 0 = ignore, 1 - error, 2 - OK */
 };
 
+/* bits for tcpcheck_rule->action */
+enum {
+	TCPCHK_ACT_SEND        = 1,             /* send action, regular string format */
+	TCPCHK_ACT_EXPECT,                      /* expect action, either regular or binary string */
+};
+
+struct tcpcheck_rule {
+	struct list list;                       /* list linked to from the proxy */
+	int action;                             /* action: send or expect */
+	/* match type uses NON-NULL pointer from either string or expect_regex below */
+	/* sent string is string */
+	char *string;                           /* sent or expected string */
+	int string_len;                         /* string lenght */
+	regex_t *expect_regex;                  /* expected */
+	int inverse;                            /* 0 = regular match, 1 = inverse match */
+};
+
 #endif /* _TYPES_CHECKS_H */
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 8b9f2fb..4883827 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -152,7 +152,8 @@
 #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 */
 #define PR_O2_LB_AGENT_CHK 0x80000000   /* use a TCP connection to obtain a metric of server health */
-/* unused: 0x90000000 to 0xF000000, reserved for health checks */
+#define PR_O2_TCPCHK_CHK 0x90000000     /* use TCPCHK check for server health */
+/* unused: 0xA0000000 to 0xF000000, reserved for health checks */
 #define PR_O2_CHK_ANY   0xF0000000      /* Mask to cover any check */
 /* end of proxy->options2 */
 
@@ -324,6 +325,7 @@
 
 	struct task *task;			/* the associated task, mandatory to manage rate limiting, stopping and resource shortage, NULL if disabled */
 	int grace;				/* grace time after stop request */
+	struct list tcpcheck_rules;		/* tcp-check send / expect rules */
 	char *check_req;			/* HTTP or SSL request to use for PR_O_HTTP_CHK|PR_O_SSL3_CHK */
 	int check_len;				/* Length of the HTTP or SSL3 request */
 	char *expect_str;			/* http-check expected content : string or text version of the regex */
diff --git a/include/types/server.h b/include/types/server.h
index 6b73a39..82eb55f 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -122,6 +122,7 @@
 	char desc[HCHK_DESC_LEN];		/* health check descritpion */
 	int use_ssl;				/* use SSL for health checks */
 	int send_proxy;				/* send a PROXY protocol header with checks */
+	struct tcpcheck_rule *current_step;     /* current step when using tcpcheck */
 	int inter, fastinter, downinter;        /* checks: time in milliseconds */
 	int result;				/* health-check result : SRV_CHK_* */
 	int state;				/* health-check result : CHK_* */