BUG/MINOR: checks: correctly configure the address family and protocol

Currently, mixing an IPv4 and an IPv6 address in checks happens to
work by pure luck because the two protocols use the same functions
at the socket level and both use IPPROTO_TCP. However, they're
definitely wrong as the protocol for the check address is retrieved
from the server's address.

Now the protocol assigned to the connection is the same as the one
the address in use belongs to (eg: the server's address or the
explicit check address).
This commit is contained in:
Willy Tarreau 2014-05-09 23:38:15 +02:00
parent 28e9d06201
commit 640556c692
2 changed files with 16 additions and 9 deletions

View File

@ -1509,6 +1509,7 @@ static struct task *process_chk(struct task *t)
struct check *check = t->context;
struct server *s = check->server;
struct connection *conn = check->conn;
struct protocol *proto;
int rv;
int ret;
int expired = tick_is_expired(t->expire, now_ms);
@ -1573,12 +1574,16 @@ static struct task *process_chk(struct task *t)
/* no client address */
clear_addr(&conn->addr.from);
if (is_addr(&s->check_common.addr))
if (is_addr(&s->check_common.addr)) {
/* we'll connect to the check addr specified on the server */
conn->addr.to = s->check_common.addr;
else
proto = s->check_common.proto;
}
else {
/* we'll connect to the addr on the server */
conn->addr.to = s->addr;
proto = s->proto;
}
if (check->port) {
set_host_port(&conn->addr.to, check->port);
@ -1606,8 +1611,8 @@ static struct task *process_chk(struct task *t)
* connect() when a pure TCP check is used (without PROXY protocol).
*/
ret = SN_ERR_INTERNAL;
if (s->check_common.proto->connect)
ret = s->check_common.proto->connect(conn, check->type, (check->type) ? 0 : 2);
if (proto->connect)
ret = proto->connect(conn, check->type, (check->type) ? 0 : 2);
conn->flags |= CO_FL_WAKE_DATA;
if (s->check.send_proxy) {
conn->send_proxy_ofs = 1;
@ -2075,15 +2080,16 @@ static void tcpcheck_main(struct connection *conn)
/* no client address */
clear_addr(&conn->addr.from);
if (is_addr(&s->check_common.addr))
if (is_addr(&s->check_common.addr)) {
/* we'll connect to the check addr specified on the server */
conn->addr.to = s->check_common.addr;
else
proto = s->check_common.proto;
}
else {
/* we'll connect to the addr on the server */
conn->addr.to = s->addr;
/* protocol */
proto = protocol_by_family(conn->addr.to.ss_family);
proto = s->proto;
}
/* port */
if (check->current_step->port)

View File

@ -597,6 +597,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
}
newsrv->check_common.addr = *sk;
newsrv->check_common.proto = protocol_by_family(sk->ss_family);
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "port")) {