]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: checks: Store the protocol to be used in struct check
authorOlivier Houchard <ohouchard@haproxy.com>
Thu, 19 Mar 2026 13:28:42 +0000 (14:28 +0100)
committerOlivier Houchard <cognet@ci0.org>
Thu, 26 Mar 2026 14:09:13 +0000 (15:09 +0100)
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

include/haproxy/check-t.h
src/check.c
src/server.c
src/tcpcheck.c

index ecb9a6862612dab3817157c86acf1663117c1f85..2be5ad2a0d3f8875ac24d706d41e75c1dfcb8b11 100644 (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 */
index 0c1bdd25b18c574ed918d3a3f0bc171ded8af9f7..e391e2e74a5241e2190a498c7bf4d0c1b3a6e13b 100644 (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;
 
index a418b7358ada4e7d3fb9bf5f1b5e576eb088b348..2a6f018173545e06602b859711b08ee96d397442 100644 (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;
 
index 3519a83e1d8f7afbfe77d690540e1437e06d99b9..3028a2a8fd95f9b2c5039505b6b4533a2349bfbd 100644 (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;