MEDIUM: check: add the ctrl and transport layers in the server check structure

Since it's possible for the checks to use a different protocol or transport layer
than the prod traffic, we need to have them referenced in the server. The
SSL checks are not enabled yet, but the transport layers are completely used.
This commit is contained in:
Willy Tarreau 2012-09-28 18:13:10 +02:00
parent 1ae1b7b53c
commit f4288ee4ba
3 changed files with 19 additions and 6 deletions

View File

@ -158,6 +158,8 @@ struct server {
struct { /* health-check specific configuration */
struct connection *conn; /* connection state for health checks */
struct protocol *proto; /* server address protocol for health checks */
struct xprt_ops *xprt; /* transport layer operations for health checks */
struct sockaddr_storage addr; /* the address to check, if different from <addr> */
short port; /* the port to use for the health checks */
struct buffer *bi, *bo; /* input and output buffers to send/recv check */
@ -166,6 +168,7 @@ struct server {
long duration; /* time in ms took to finish last health check */
short status, code; /* check result, check code */
char desc[HCHK_DESC_LEN]; /* health check descritpion */
int use_ssl; /* use SSL for health checks */
} check;
#ifdef USE_OPENSSL

View File

@ -3948,8 +3948,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
goto out;
}
newsrv->addr = *sk;
newsrv->proto = protocol_by_family(newsrv->addr.ss_family);
newsrv->xprt = &raw_sock;
newsrv->proto = newsrv->check.proto = protocol_by_family(newsrv->addr.ss_family);
newsrv->xprt = newsrv->check.xprt = &raw_sock;
if (!newsrv->proto) {
Alert("parsing [%s:%d] : Unknown protocol family %d '%s'\n",
@ -3959,6 +3959,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
}
set_host_port(&newsrv->addr, realport);
newsrv->check.use_ssl = curproxy->defsrv.check.use_ssl;
newsrv->check.port = curproxy->defsrv.check.port;
newsrv->inter = curproxy->defsrv.inter;
newsrv->fastinter = curproxy->defsrv.fastinter;
@ -4549,6 +4550,14 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
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))
newsrv->check.use_ssl |= newsrv->use_ssl;
/* try to get the port from check.addr if check.port not set */
if (!newsrv->check.port)
newsrv->check.port = get_host_port(&newsrv->check.addr);
@ -6271,7 +6280,7 @@ int check_config_validity()
#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
#define SSL_OP_NO_TLSv1_2 0
#endif
if (newsrv->use_ssl) {
if (newsrv->use_ssl || newsrv->check.use_ssl) {
int ssloptions =
SSL_OP_ALL | /* all known workarounds for bugs */
SSL_OP_NO_SSLv2 |
@ -6283,7 +6292,8 @@ int check_config_validity()
/* Initiate SSL context for current server */
newsrv->ssl_ctx.reused_sess = NULL;
newsrv->xprt = &ssl_sock;
if (newsrv->use_ssl)
newsrv->xprt = &ssl_sock;
newsrv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
if(!newsrv->ssl_ctx.ctx) {

View File

@ -1375,7 +1375,7 @@ static struct task *process_chk(struct task *t)
/* prepare a new connection */
set_target_server(&conn->target, s);
conn_prepare(conn, &check_conn_cb, s->proto, &raw_sock, s);
conn_prepare(conn, &check_conn_cb, s->check.proto, s->check.xprt, s);
if (is_addr(&s->check.addr))
/* we'll connect to the check addr specified on the server */
@ -1395,7 +1395,7 @@ static struct task *process_chk(struct task *t)
* - SN_ERR_INTERNAL for any other purely internal errors
* Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
*/
ret = tcp_connect_server(conn, 1);
ret = s->check.proto->connect(conn, 1);
conn->flags |= CO_FL_WAKE_DATA;
switch (ret) {