MEDIUM: checks: Add check-alpn.

Add a way to configure the ALPN used by check, with a new "check-alpn"
keyword. By default, the checks will use the server ALPN, but it may not
be convenient, for instance because the server may use HTTP/2, while checks
are unable to do HTTP/2 yet.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 822a5c5..d81cdcd 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -11569,6 +11569,11 @@
   "check-send-proxy" option needs to be used to force the use of the
   protocol. See also the "send-proxy" option for more information.
 
+check-alpn <protocols>
+  Defines which protocols to advertise with ALPN. The protocol list consists in
+  a comma-delimited list of protocol names, for instance: "http/1.1,http/1.0"
+  (without quotes). If it is not set, the server ALPN is used.
+
 check-sni <sni>
   This option allows you to specify the SNI to be used when doing health checks
   over SSL. It is only possible to use a string to set <sni>. If you want to
diff --git a/include/types/checks.h b/include/types/checks.h
index 364eee8..6346fe3 100644
--- a/include/types/checks.h
+++ b/include/types/checks.h
@@ -186,6 +186,8 @@
 	struct sockaddr_storage addr;   	/* the address to check */
 	struct wait_event wait_list;            /* Waiting for I/O events */
 	char *sni;				/* Server name */
+	char *alpn_str;                         /* ALPN to use for checks */
+	int alpn_len;                           /* ALPN string length */
 };
 
 struct check_status {
diff --git a/src/checks.c b/src/checks.c
index cb89f2f..4baaf9f 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -1621,6 +1621,9 @@
 #ifdef USE_OPENSSL
 	if (s->check.sni)
 		ssl_sock_set_servername(conn, s->check.sni);
+	if (s->check.alpn_str)
+		ssl_sock_set_alpn(conn, (unsigned char *)s->check.alpn_str,
+		    s->check.alpn_len);
 #endif
 	if (s->check.send_proxy && !(check->state & CHK_ST_AGENT)) {
 		conn->send_proxy_ofs = 1;
diff --git a/src/server.c b/src/server.c
index 24732b3..4cd8784 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1613,6 +1613,8 @@
 	srv->check.use_ssl            = src->check.use_ssl;
 	srv->check.port               = src->check.port;
 	srv->check.sni                = src->check.sni;
+	srv->check.alpn_str           = src->check.alpn_str;
+	srv->check.alpn_len           = srv->check.alpn_len;
 	/* Note: 'flags' field has potentially been already initialized. */
 	srv->flags                   |= src->flags;
 	srv->do_check                 = src->do_check;
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index d45e3e2..282b85d 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -7966,34 +7966,42 @@
 #endif
 }
 
-/* parse the "alpn" bind keyword */
+/* parse the "alpn" or the "check-alpn" server keyword */
 static int srv_parse_alpn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
 {
 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
 	char *p1, *p2;
+	char **alpn_str;
+	int *alpn_len;
 
+	if (*args[*cur_arg] == 'c') {
+		alpn_str = &newsrv->check.alpn_str;
+		alpn_len = &newsrv->check.alpn_len;
+	} else {
+		alpn_str = &newsrv->ssl_ctx.alpn_str;
+		alpn_len = &newsrv->ssl_ctx.alpn_len;
+
+	}
 	if (!*args[*cur_arg + 1]) {
 		memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[*cur_arg]);
 		return ERR_ALERT | ERR_FATAL;
 	}
 
-	free(newsrv->ssl_ctx.alpn_str);
+	free(*alpn_str);
 
 	/* the ALPN string is built as a suite of (<len> <name>)*,
 	 * so we reuse each comma to store the next <len> and need
 	 * one more for the end of the string.
 	 */
-	newsrv->ssl_ctx.alpn_len = strlen(args[*cur_arg + 1]) + 1;
-	newsrv->ssl_ctx.alpn_str = calloc(1, newsrv->ssl_ctx.alpn_len + 1);
-	memcpy(newsrv->ssl_ctx.alpn_str + 1, args[*cur_arg + 1],
-	    newsrv->ssl_ctx.alpn_len);
+	*alpn_len = strlen(args[*cur_arg + 1]) + 1;
+	*alpn_str = calloc(1, *alpn_len + 1);
+	memcpy(*alpn_str + 1, args[*cur_arg + 1], *alpn_len);
 
 	/* replace commas with the name length */
-	p1 = newsrv->ssl_ctx.alpn_str;
+	p1 = *alpn_str;
 	p2 = p1 + 1;
 	while (1) {
-		p2 = memchr(p1 + 1, ',', newsrv->ssl_ctx.alpn_str +
-		    newsrv->ssl_ctx.alpn_len - (p1 + 1));
+		p2 = memchr(p1 + 1, ',', *alpn_str + *alpn_len - (p1 + 1));
 		if (!p2)
 			p2 = p1 + 1 + strlen(p1 + 1);
 
@@ -9132,6 +9140,7 @@
 	{ "allow-0rtt",              srv_parse_allow_0rtt,         0, 1 }, /* Allow using early data on this server */
 	{ "alpn",                    srv_parse_alpn,               1, 1 }, /* Set ALPN supported protocols */
 	{ "ca-file",                 srv_parse_ca_file,            1, 1 }, /* set CAfile to process verify server cert */
+	{ "check-alpn",              srv_parse_alpn,               1, 1 }, /* Set ALPN used for checks */
 	{ "check-sni",               srv_parse_check_sni,          1, 1 }, /* set SNI */
 	{ "check-ssl",               srv_parse_check_ssl,          0, 1 }, /* enable SSL for health checks */
 	{ "ciphers",                 srv_parse_ciphers,            1, 1 }, /* select the cipher suite */