Add a new parameter "alt" that will store wether this configuration
use an alternate protocol.

This alt pointer will contain a value that can be transparently
passed to protocol_lookup to obtain an appropriate protocol structure.

This change is needed to allow for example the servers to know if it
need to use an alternate protocol or not. 
---
 include/haproxy/protocol.h |  4 ++--
 include/haproxy/tools.h    |  2 +-
 src/cfgparse-listen.c      |  8 +++++---
 src/cfgparse.c             |  6 +++---
 src/check.c                |  2 +-
 src/cli.c                  |  2 +-
 src/hlua.c                 |  3 ++-
 src/http_client.c          |  2 +-
 src/log.c                  |  2 +-
 src/resolvers.c            |  3 ++-
 src/server.c               |  8 ++++----
 src/ssl_ocsp.c             |  2 +-
 src/tcpcheck.c             |  3 ++-
 src/tools.c                | 15 ++++++++++++---
 14 files changed, 38 insertions(+), 24 deletions(-)

diff --git a/include/haproxy/protocol.h b/include/haproxy/protocol.h
index 475ac5ebb..7b14e1581 100644
--- a/include/haproxy/protocol.h
+++ b/include/haproxy/protocol.h
@@ -95,10 +95,10 @@ int protocol_enable_all(void);
  * supported protocol types, and ctrl_type of either SOCK_STREAM or SOCK_DGRAM
  * depending on the requested values, or NULL if not found.
  */
-static inline struct protocol *protocol_lookup(int family, enum proto_type 
proto_type, int ctrl_dgram)
+static inline struct protocol *protocol_lookup(int family, enum proto_type 
proto_type, int alt)
 {
        if (family >= 0 && family < AF_CUST_MAX)
-               return __protocol_by_family[family][proto_type][!!ctrl_dgram];
+               return __protocol_by_family[family][proto_type][!!alt];
        return NULL;
 }
 
diff --git a/include/haproxy/tools.h b/include/haproxy/tools.h
index fd078c7da..1e487d0e1 100644
--- a/include/haproxy/tools.h
+++ b/include/haproxy/tools.h
@@ -286,7 +286,7 @@ static inline int is_idchar(char c)
  */
 struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, 
int *high, int *fd,
                                       struct protocol **proto, struct 
net_addr_type *sa_type,
-                                      char **err, const char *pfx, char 
**fqdn, unsigned int opts);
+                                      char **err, const char *pfx, char 
**fqdn, int *alt, unsigned int opts);
 
 
 /* converts <addr> and <port> into a string representation of the address and 
port. This is sort
diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c
index 2cab44109..9f2786e8d 100644
--- a/src/cfgparse-listen.c
+++ b/src/cfgparse-listen.c
@@ -2497,7 +2497,7 @@ int cfg_parse_listen(const char *file, int linenum, char 
**args, int kwm)
                        err_code |= ERR_WARN;
 
                sk = str2sa_range(args[1], NULL, &port1, &port2, NULL, NULL, 
NULL,
-                                 &errmsg, NULL, NULL,
+                                 &errmsg, NULL, NULL, NULL,
                                  PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND 
| PA_O_STREAM | PA_O_XPRT | PA_O_CONNECT);
                if (!sk) {
                        ha_alert("parsing [%s:%d] : '%s' : %s\n", file, 
linenum, args[0], errmsg);
@@ -2786,7 +2786,8 @@ int cfg_parse_listen(const char *file, int linenum, char 
**args, int kwm)
                curproxy->conn_src.iface_len = 0;
 
                sk = str2sa_range(args[1], NULL, &port1, &port2, NULL, NULL, 
NULL,
-                                 &errmsg, NULL, NULL, PA_O_RESOLVE | 
PA_O_PORT_OK | PA_O_STREAM | PA_O_CONNECT);
+                                 &errmsg, NULL, NULL, NULL,
+                                 PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM | 
PA_O_CONNECT);
                if (!sk) {
                        ha_alert("parsing [%s:%d] : '%s %s' : %s\n",
                                 file, linenum, args[0], args[1], errmsg);
@@ -2860,7 +2861,8 @@ int cfg_parse_listen(const char *file, int linenum, char 
**args, int kwm)
                                        struct sockaddr_storage *sk;
 
                                        sk = str2sa_range(args[cur_arg + 1], 
NULL, &port1, &port2, NULL, NULL, NULL,
-                                                         &errmsg, NULL, NULL, 
PA_O_RESOLVE | PA_O_PORT_OK | PA_O_STREAM | PA_O_CONNECT);
+                                                         &errmsg, NULL, NULL, 
NULL,
+                                                         PA_O_RESOLVE | 
PA_O_PORT_OK | PA_O_STREAM | PA_O_CONNECT);
                                        if (!sk) {
                                                ha_alert("parsing [%s:%d] : '%s 
%s' : %s\n",
                                                         file, linenum, 
args[cur_arg], args[cur_arg+1], errmsg);
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 4296e47e8..d90fdc5ea 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -158,7 +158,7 @@ int str2listener(char *str, struct proxy *curproxy, struct 
bind_conf *bind_conf,
 
                ss2 = str2sa_range(str, NULL, &port, &end, &fd, &proto, NULL, 
err,
                                   (curproxy == global.cli_fe || curproxy == 
mworker_proxy) ? NULL : global.unix_bind.prefix,
-                                  NULL, PA_O_RESOLVE | PA_O_PORT_OK | 
PA_O_PORT_MAND | PA_O_PORT_RANGE |
+                                  NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | 
PA_O_PORT_MAND | PA_O_PORT_RANGE |
                                          PA_O_SOCKET_FD | PA_O_STREAM | 
PA_O_XPRT);
                if (!ss2)
                        goto fail;
@@ -244,7 +244,7 @@ int str2receiver(char *str, struct proxy *curproxy, struct 
bind_conf *bind_conf,
 
                ss2 = str2sa_range(str, NULL, &port, &end, &fd, &proto, NULL, 
err,
                                   curproxy == global.cli_fe ? NULL : 
global.unix_bind.prefix,
-                                  NULL, PA_O_RESOLVE | PA_O_PORT_OK | 
PA_O_PORT_MAND | PA_O_PORT_RANGE |
+                                  NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | 
PA_O_PORT_MAND | PA_O_PORT_RANGE |
                                          PA_O_SOCKET_FD | PA_O_DGRAM | 
PA_O_XPRT);
                if (!ss2)
                        goto fail;
@@ -1185,7 +1185,7 @@ int cfg_parse_mailers(const char *file, int linenum, char 
**args, int kwm)
                newmailer->id = strdup(args[1]);
 
                sk = str2sa_range(args[2], NULL, &port1, &port2, NULL, &proto, 
NULL,
-                                 &errmsg, NULL, NULL,
+                                 &errmsg, NULL, NULL, NULL,
                                  PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND 
| PA_O_STREAM | PA_O_XPRT | PA_O_CONNECT);
                if (!sk) {
                        ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, 
linenum, args[0], args[1], errmsg);
diff --git a/src/check.c b/src/check.c
index 40d403b27..1474a55f9 100644
--- a/src/check.c
+++ b/src/check.c
@@ -2032,7 +2032,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,
+       sk = str2sa_range(args[*cur_arg+1], NULL, &port1, &port2, NULL, NULL, 
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);
diff --git a/src/cli.c b/src/cli.c
index 81422e860..3e0ec1e50 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -3335,7 +3335,7 @@ int mworker_cli_proxy_create()
 
                memprintf(&msg, "sockpair@%d", child->ipc_fd[0]);
                if ((sk = str2sa_range(msg, &port, &port1, &port2, NULL, 
&proto, NULL,
-                                      &errmsg, NULL, NULL, PA_O_STREAM)) == 0) 
{
+                                      &errmsg, NULL, NULL, NULL, PA_O_STREAM)) 
== 0) {
                        goto error;
                }
                ha_free(&msg);
diff --git a/src/hlua.c b/src/hlua.c
index 30bd34edd..96773a86a 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -3519,7 +3519,8 @@ __LJMP static int hlua_socket_connect(struct lua_State *L)
                csk_ctx->srv = socket_tcp;
 
        /* Parse ip address. */
-       addr = str2sa_range(ip, NULL, &low, &high, NULL, NULL, NULL, NULL, 
NULL, NULL, PA_O_PORT_OK | PA_O_STREAM);
+       addr = str2sa_range(ip, NULL, &low, &high, NULL, NULL, NULL, NULL,
+                           NULL, NULL, NULL, PA_O_PORT_OK | PA_O_STREAM);
        if (!addr) {
                xref_unlock(&socket->xref, peer);
                WILL_LJMP(luaL_error(L, "connect: cannot parse destination 
address '%s'", ip));
diff --git a/src/http_client.c b/src/http_client.c
index 6deff05bd..5db0e175c 100644
--- a/src/http_client.c
+++ b/src/http_client.c
@@ -455,7 +455,7 @@ int httpclient_set_dst(struct httpclient *hc, const char 
*dst)
        sockaddr_free(&hc->dst);
        /* 'sk' is statically allocated (no need to be freed). */
        sk = str2sa_range(dst, NULL, NULL, NULL, NULL, NULL, NULL,
-                         &errmsg, NULL, NULL,
+                         &errmsg, NULL, NULL, NULL,
                          PA_O_PORT_OK | PA_O_STREAM | PA_O_XPRT | 
PA_O_CONNECT);
        if (!sk) {
                ha_alert("httpclient: Failed to parse destination address in 
%s\n", errmsg);
diff --git a/src/log.c b/src/log.c
index d1f285a39..993fe08e8 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1600,7 +1600,7 @@ static int parse_log_target(char *raw, struct log_target 
*target, char **err)
 
        /* parse the target address */
        sk = str2sa_range(raw, NULL, &port1, &port2, &fd, &proto, NULL,
-                         err, NULL, NULL,
+                         err, NULL, NULL, NULL,
                          PA_O_RESOLVE | PA_O_PORT_OK | PA_O_RAW_FD | 
PA_O_DGRAM | PA_O_STREAM | PA_O_DEFAULT_DGRAM);
        if (!sk)
                goto error;
diff --git a/src/resolvers.c b/src/resolvers.c
index 33a9bbd79..99b4ef0cf 100644
--- a/src/resolvers.c
+++ b/src/resolvers.c
@@ -3616,7 +3616,8 @@ int cfg_parse_resolvers(const char *file, int linenum, 
char **args, int kwm)
                }
 
                sk = str2sa_range(args[2], NULL, &port1, &port2, NULL, &proto, 
NULL,
-                                 &errmsg, NULL, NULL, PA_O_RESOLVE | 
PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_DGRAM | PA_O_STREAM | PA_O_DEFAULT_DGRAM);
+                                 &errmsg, NULL, NULL, NULL,
+                                 PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND 
| PA_O_DGRAM | PA_O_STREAM | PA_O_DEFAULT_DGRAM);
                if (!sk) {
                        ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, 
linenum, args[0], args[1], errmsg);
                        err_code |= ERR_ALERT | ERR_FATAL;
diff --git a/src/server.c b/src/server.c
index c6f39012f..a4f78cc66 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1749,7 +1749,7 @@ static int srv_parse_source(char **args, int *cur_arg,
 
        /* 'sk' is statically allocated (no need to be freed). */
        sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, 
NULL, NULL, NULL,
-                         &errmsg, NULL, NULL,
+                         &errmsg, NULL, NULL, NULL,
                          PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_RANGE | 
PA_O_STREAM | PA_O_CONNECT);
        if (!sk) {
                memprintf(err, "'%s %s' : %s\n", args[*cur_arg], args[*cur_arg 
+ 1], errmsg);
@@ -1837,7 +1837,7 @@ static int srv_parse_source(char **args, int *cur_arg,
 
                                /* 'sk' is statically allocated (no need to be 
freed). */
                                sk = str2sa_range(args[*cur_arg + 1], NULL, 
&port1, &port2, NULL, NULL, NULL,
-                                                 &errmsg, NULL, NULL,
+                                                 &errmsg, NULL, NULL, NULL,
                                                  PA_O_RESOLVE | PA_O_PORT_OK | 
PA_O_STREAM | PA_O_CONNECT);
                                if (!sk) {
                                        ha_alert("'%s %s' : %s\n", 
args[*cur_arg], args[*cur_arg + 1], errmsg);
@@ -1927,7 +1927,7 @@ static int srv_parse_socks4(char **args, int *cur_arg,
 
        /* 'sk' is statically allocated (no need to be freed). */
        sk = str2sa_range(args[*cur_arg + 1], NULL, &port_low, &port_high, 
NULL, NULL, NULL,
-                         &errmsg, NULL, NULL,
+                         &errmsg, NULL, NULL, NULL,
                          PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | 
PA_O_STREAM | PA_O_CONNECT);
        if (!sk) {
                memprintf(err, "'%s %s' : %s\n", args[*cur_arg], args[*cur_arg 
+ 1], errmsg);
@@ -3396,7 +3396,7 @@ static int _srv_parse_init(struct server **srv, char 
**args, int *cur_arg,
                        goto skip_addr;
 
                sk = str2sa_range(args[*cur_arg], &port, &port1, &port2, NULL, 
NULL, &newsrv->addr_type,
-                                 &errmsg, NULL, &fqdn,
+                                 &errmsg, NULL, &fqdn, NULL,
                                  (parse_flags & SRV_PARSE_INITIAL_RESOLVE ? 
PA_O_RESOLVE : 0) | PA_O_PORT_OK |
                                  (parse_flags & SRV_PARSE_IN_PEER_SECTION ? 
PA_O_PORT_MAND : PA_O_PORT_OFS) |
                                  PA_O_STREAM | PA_O_DGRAM | PA_O_XPRT);
diff --git a/src/ssl_ocsp.c b/src/ssl_ocsp.c
index 7d3a485b8..19bb92ac3 100644
--- a/src/ssl_ocsp.c
+++ b/src/ssl_ocsp.c
@@ -1970,7 +1970,7 @@ static int ocsp_update_parse_global_http_proxy(char 
**args, int section_type, st
        sockaddr_free(&ocsp_update_dst);
        /* 'sk' is statically allocated (no need to be freed). */
        sk = str2sa_range(args[1], NULL, NULL, NULL, NULL, NULL, NULL,
-                         &errmsg, NULL, NULL,
+                         &errmsg, NULL, NULL, NULL,
                          PA_O_PORT_OK | PA_O_STREAM | PA_O_XPRT | 
PA_O_CONNECT);
        if (!sk) {
                ha_alert("ocsp-update: Failed to parse destination address in 
%s\n", errmsg);
diff --git a/src/tcpcheck.c b/src/tcpcheck.c
index 5e3775ba6..d5bd796f3 100644
--- a/src/tcpcheck.c
+++ b/src/tcpcheck.c
@@ -2558,7 +2558,8 @@ struct tcpcheck_rule *parse_tcpcheck_connect(char **args, 
int cur_arg, struct pr
                        }
 
                        sk = str2sa_range(args[cur_arg+1], NULL, &port1, 
&port2, NULL, NULL, NULL,
-                                         errmsg, NULL, NULL, PA_O_RESOLVE | 
PA_O_PORT_OK | PA_O_STREAM | PA_O_CONNECT);
+                                         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);
                                goto error;
diff --git a/src/tools.c b/src/tools.c
index 39bb454e3..662ba3a6e 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -967,7 +967,7 @@ struct sockaddr_storage *str2ip2(const char *str, struct 
sockaddr_storage *sa, i
  */
 struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, 
int *high, int *fd,
                                       struct protocol **proto, struct 
net_addr_type *sa_type,
-                                      char **err, const char *pfx, char 
**fqdn, unsigned int opts)
+                                      char **err, const char *pfx, char 
**fqdn, int *alt, unsigned int opts)
 {
        static THREAD_LOCAL struct sockaddr_storage ss;
        struct sockaddr_storage *ret = NULL;
@@ -979,6 +979,7 @@ struct sockaddr_storage *str2sa_range(const char *str, int 
*port, int *low, int
        int new_fd = -1;
        enum proto_type proto_type = 0; // to shut gcc warning
        int ctrl_type = 0; // to shut gcc warning
+       int alt_proto = 0;
 
        portl = porth = porta = 0;
        if (fqdn)
@@ -1002,6 +1003,7 @@ struct sockaddr_storage *str2sa_range(const char *str, 
int *port, int *low, int
            ((opts & (PA_O_STREAM|PA_O_DGRAM)) == (PA_O_DGRAM|PA_O_STREAM) && 
(opts & PA_O_DEFAULT_DGRAM))) {
                proto_type = PROTO_TYPE_DGRAM;
                ctrl_type = SOCK_DGRAM;
+               alt_proto = 1;
        } else {
                proto_type = PROTO_TYPE_STREAM;
                ctrl_type = SOCK_STREAM;
@@ -1016,6 +1018,7 @@ struct sockaddr_storage *str2sa_range(const char *str, 
int *port, int *low, int
                str2 += 6;
                proto_type = PROTO_TYPE_DGRAM;
                ctrl_type = SOCK_DGRAM;
+               alt_proto = 1;
        }
        else if (strncmp(str2, "quic+", 5) == 0) {
                str2 += 5;
@@ -1034,6 +1037,7 @@ struct sockaddr_storage *str2sa_range(const char *str, 
int *port, int *low, int
                ss.ss_family = AF_UNIX;
                proto_type = PROTO_TYPE_DGRAM;
                ctrl_type = SOCK_DGRAM;
+               alt_proto = 1;
        }
        else if (strncmp(str2, "uxst@", 5) == 0) {
                str2 += 5;
@@ -1070,6 +1074,7 @@ struct sockaddr_storage *str2sa_range(const char *str, 
int *port, int *low, int
                ss.ss_family = AF_INET;
                proto_type = PROTO_TYPE_DGRAM;
                ctrl_type = SOCK_DGRAM;
+               alt_proto = 1;
        }
        else if (strncmp(str2, "tcp6@", 5) == 0) {
                str2 += 5;
@@ -1082,6 +1087,7 @@ struct sockaddr_storage *str2sa_range(const char *str, 
int *port, int *low, int
                ss.ss_family = AF_INET6;
                proto_type = PROTO_TYPE_DGRAM;
                ctrl_type = SOCK_DGRAM;
+               alt_proto = 1;
        }
        else if (strncmp(str2, "tcp@", 4) == 0) {
                str2 += 4;
@@ -1094,6 +1100,7 @@ struct sockaddr_storage *str2sa_range(const char *str, 
int *port, int *low, int
                ss.ss_family = AF_UNSPEC;
                proto_type = PROTO_TYPE_DGRAM;
                ctrl_type = SOCK_DGRAM;
+               alt_proto = 1;
        }
        else if (strncmp(str2, "quic4@", 6) == 0) {
                str2 += 6;
@@ -1367,7 +1374,7 @@ struct sockaddr_storage *str2sa_range(const char *str, 
int *port, int *low, int
                 */
                new_proto = protocol_lookup(ss.ss_family,
                                            proto_type,
-                                           ctrl_type == SOCK_DGRAM);
+                                           alt_proto);
 
                if (!new_proto && (!fqdn || !*fqdn) && (ss.ss_family != 
AF_CUST_EXISTING_FD)) {
                        memprintf(err, "unsupported %s protocol for %s family 
%d address '%s'%s",
@@ -1408,6 +1415,8 @@ struct sockaddr_storage *str2sa_range(const char *str, 
int *port, int *low, int
                sa_type->proto_type = proto_type;
                sa_type->xprt_type = (ctrl_type == SOCK_DGRAM) ? 
PROTO_TYPE_DGRAM : PROTO_TYPE_STREAM;
        }
+       if (alt)
+               *alt = alt_proto;
        free(back);
        return ret;
 }
@@ -6310,7 +6319,7 @@ const char *hash_ipanon(uint32_t scramble, char 
*ipstring, int hasport)
                        sa = &ss;
                }
                else {
-                       sa = str2sa_range(ipstring, NULL, NULL, NULL, NULL, 
NULL, NULL, &errmsg, NULL, NULL,
+                       sa = str2sa_range(ipstring, NULL, NULL, NULL, NULL, 
NULL, NULL, &errmsg, NULL, NULL, NULL,
                                          PA_O_PORT_OK | PA_O_STREAM | 
PA_O_DGRAM | PA_O_XPRT | PA_O_CONNECT |
                                          PA_O_PORT_RANGE | PA_O_PORT_OFS | 
PA_O_RESOLVE);
                        if (sa == NULL) {
-- 
2.46.0



Reply via email to