MAJOR: check: find out which port to use for health check at run time
HAProxy used to deduce port used for health checks when parsing configuration
at startup time.
Because of this way of working, it makes it complicated to change the port at
run time.
The current patch changes this behavior and makes HAProxy to choose the
port used for health checking when preparing the check task itself.
A new type of error is introduced and reported when no port can be found.
There won't be any impact on performance, since the process to find out the
port value is made of a few 'if' statements.
This patch also introduces a new check state CHK_ST_PORT_MISS: this flag is
used to report an error in the case when HAProxy needs to establish a TCP
connection to a server, to perform a health check but no TCP ports can be
found for it.
And last, it also introduces a new stream termination condition:
SF_ERR_CHK_PORT. Purpose of this flag is to report an error in the event when
HAProxy has to run a health check but no port can be found to perform it.
diff --git a/src/server.c b/src/server.c
index 62c08b0..e41afc7 100644
--- a/src/server.c
+++ b/src/server.c
@@ -869,7 +869,6 @@
if (!strcmp(args[0], "server") || !strcmp(args[0], "default-server")) { /* server address */
int cur_arg;
- short realport = 0;
int do_agent = 0, do_check = 0, defsrv = (*args[0] == 'd');
if (!defsrv && curproxy == defproxy) {
@@ -961,10 +960,6 @@
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
- else {
- /* used by checks */
- realport = port1;
- }
/* save hostname and create associated name resolution */
newsrv->hostname = fqdn;
@@ -1749,29 +1744,11 @@
goto out;
}
- /* If neither a port nor an addr was specified and no check transport
- * layer is forced, then the transport layer used by the checks is the
- * same as for the production traffic. Otherwise we use raw_sock by
- * default, unless one is specified.
- */
- if (!newsrv->check.port && !is_addr(&newsrv->check.addr)) {
-#ifdef USE_OPENSSL
- newsrv->check.use_ssl |= (newsrv->use_ssl || (newsrv->proxy->options & PR_O_TCPCHK_SSL));
-#endif
- newsrv->check.send_proxy |= (newsrv->pp_opts);
- }
- /* try to get the port from check_core.addr if check.port not set */
- if (!newsrv->check.port)
- newsrv->check.port = get_host_port(&newsrv->check.addr);
-
- if (!newsrv->check.port)
- newsrv->check.port = realport; /* by default */
-
/*
* We need at least a service port, a check port or the first tcp-check rule must
* be a 'connect' one when checking an IPv4/IPv6 server.
*/
- if (!newsrv->check.port &&
+ if ((srv_check_healthcheck_port(&newsrv->check) == 0) &&
(is_inet_addr(&newsrv->check.addr) ||
(!is_addr(&newsrv->check.addr) && is_inet_addr(&newsrv->addr)))) {
struct tcpcheck_rule *r = NULL;