MINOR: checks: Store the protocol to be used in struct check

When parsing the check address, store the associated proto too.
That way we can use the notation like quic4@address, and the right
protocol will be used. It is possible for checks to use a different
protocol than the server, ie we can have a QUIC server but want to run
TCP checks, so we can't just reuse whatever the server uses.
WIP: store the protocol in checks
This commit is contained in:
Olivier Houchard 2026-03-19 14:28:42 +01:00 committed by Olivier Houchard
parent 07edaed191
commit cca9245416
4 changed files with 34 additions and 9 deletions

View file

@ -189,6 +189,7 @@ struct check {
char **envp; /* the environment to use if running a process-based check */
struct pid_list *curpid; /* entry in pid_list used for current process-based test, or -1 if not in test */
struct sockaddr_storage addr; /* the address to check */
struct protocol *proto; /* protocol used for check, may be different from the server's one */
char *pool_conn_name; /* conn name used on reuse */
char *sni; /* Server name */
char *alpn_str; /* ALPN to use for checks */

View file

@ -2072,6 +2072,7 @@ static int srv_parse_addr(char **args, int *cur_arg, struct proxy *curpx, struct
char **errmsg)
{
struct sockaddr_storage *sk;
struct protocol *proto;
int port1, port2, err_code = 0;
@ -2080,7 +2081,7 @@ static int srv_parse_addr(char **args, int *cur_arg, struct proxy *curpx, struct
goto error;
}
sk = str2sa_range(args[*cur_arg+1], NULL, &port1, &port2, NULL, NULL, NULL, errmsg, NULL, NULL, NULL,
sk = str2sa_range(args[*cur_arg+1], NULL, &port1, &port2, NULL, &proto, NULL, errmsg, NULL, NULL, NULL,
PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM | PA_O_CONNECT);
if (!sk) {
memprintf(errmsg, "'%s' : %s", args[*cur_arg], *errmsg);
@ -2088,6 +2089,7 @@ static int srv_parse_addr(char **args, int *cur_arg, struct proxy *curpx, struct
}
srv->check.addr = *sk;
srv->check.proto = proto;
/* if agentaddr was never set, we can use addr */
if (!(srv->flags & SRV_F_AGENTADDR))
srv->agent.addr = *sk;
@ -2117,7 +2119,11 @@ static int srv_parse_agent_addr(char **args, int *cur_arg, struct proxy *curpx,
goto error;
}
set_srv_agent_addr(srv, &sk);
/* Agent currently only uses TCP */
if (sk.ss_family == AF_INET)
srv->agent.proto = &proto_tcpv4;
else
srv->agent.proto = &proto_tcpv6;
out:
return err_code;

View file

@ -37,6 +37,7 @@
#include <haproxy/namespace.h>
#include <haproxy/port_range.h>
#include <haproxy/protocol.h>
#include <haproxy/proto_tcp.h>
#include <haproxy/proxy.h>
#include <haproxy/queue.h>
#include <haproxy/quic_tp.h>
@ -2938,7 +2939,9 @@ void srv_settings_cpy(struct server *srv, const struct server *src, int srv_tmpl
}
srv->use_ssl = src->use_ssl;
srv->check.addr = src->check.addr;
srv->check.proto = src->check.proto;
srv->agent.addr = src->agent.addr;
srv->agent.proto = src->agent.proto;
srv->check.use_ssl = src->check.use_ssl;
srv->check.port = src->check.port;
if (src->check.sni != NULL)
@ -4635,6 +4638,11 @@ out:
set_srv_agent_addr(s, &sk);
if (port)
set_srv_agent_port(s, new_port);
/* Agent currently only uses TCP */
if (sk.ss_family == AF_INET)
s->agent.proto = &proto_tcpv4;
else
s->agent.proto = &proto_tcpv6;
}
return NULL;
}
@ -4646,7 +4654,8 @@ out:
*/
const char *srv_update_check_addr_port(struct server *s, const char *addr, const char *port)
{
struct sockaddr_storage sk;
struct sockaddr_storage *sk = NULL;
struct protocol *proto = NULL;
struct buffer *msg;
int new_port;
@ -4659,7 +4668,8 @@ const char *srv_update_check_addr_port(struct server *s, const char *addr, const
}
if (addr) {
memset(&sk, 0, sizeof(struct sockaddr_storage));
if (str2ip2(addr, &sk, 0) == NULL) {
sk = str2sa_range(addr, NULL, NULL, NULL, NULL, &proto, NULL, NULL, NULL, NULL, NULL, 0);
if (sk == NULL) {
chunk_appendf(msg, "invalid addr '%s'", addr);
goto out;
}
@ -4683,8 +4693,10 @@ out:
if (msg->data)
return msg->area;
else {
if (addr)
s->check.addr = sk;
if (sk) {
s->check.addr = *sk;
s->check.proto = proto;
}
if (port)
s->check.port = new_port;

View file

@ -1428,9 +1428,15 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
check->mux_proto = NULL;
}
else {
proto = s ?
protocol_lookup(conn->dst->ss_family, s->addr_type.proto_type, s->alt_proto) :
protocol_lookup(conn->dst->ss_family, PROTO_TYPE_STREAM, 0);
if (check->proto)
proto = check->proto;
else {
if (is_addr(&connect->addr))
proto = protocol_lookup(conn->dst->ss_family, PROTO_TYPE_STREAM, 0);
else
proto = protocol_lookup(conn->dst->ss_family, s->addr_type.proto_type, s->alt_proto);
}
}
port = 0;