From: Olivier Houchard Date: Thu, 19 Mar 2026 13:28:42 +0000 (+0100) Subject: MINOR: checks: Store the protocol to be used in struct check X-Git-Tag: v3.4-dev8~107 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cca92454161b704abcfad9abb217164fca828007;p=thirdparty%2Fhaproxy.git 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 --- diff --git a/include/haproxy/check-t.h b/include/haproxy/check-t.h index ecb9a6862..2be5ad2a0 100644 --- a/include/haproxy/check-t.h +++ b/include/haproxy/check-t.h @@ -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 */ diff --git a/src/check.c b/src/check.c index 0c1bdd25b..e391e2e74 100644 --- a/src/check.c +++ b/src/check.c @@ -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; diff --git a/src/server.c b/src/server.c index a418b7358..2a6f01817 100644 --- a/src/server.c +++ b/src/server.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -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; diff --git a/src/tcpcheck.c b/src/tcpcheck.c index 3519a83e1..3028a2a8f 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -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;