From be8159248fcfc5064baf9deaaf6f294bc48dfda7 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 26 Jun 2026 10:36:55 +0200 Subject: [PATCH] MAJOR: proxy: remove support for "dispatch" and "transparent" proxy keywords These ones were deprecated in 3.3-dev2 with commits 5c15ba5eff ("MEDIUM: proxy: mark the "dispatch" directive as deprecated") and e93f3ea3f8 ("MEDIUM: proxy: deprecate the "transparent" and "option transparent" directives"), and were planned for removal in 3.5. See also: https://github.com/orgs/haproxy/discussions/2921 as well as the wiki page about breaking changes. They've lived their lives and always cause internal limitations (exceptions between connecting to server or connecting to proxy), and are even confusing to some extents (especially "transparent" which users often get wrong). This commit removes the ability to configure them, tests based on them and all the doc related to them. The keywords remain detected by the parser and indicate how to proceed instead. It's likely that other deeper parts will be changed as well (e.g. conn->target will no longer be of OBJ_TYPE_PROXY). This will be done over the long term. --- doc/configuration.txt | 125 +----------------------------- doc/management.txt | 3 +- include/haproxy/proxy-t.h | 9 +-- reg-tests/connection/dispatch.vtc | 50 ------------ src/backend.c | 19 ----- src/cfgparse-listen.c | 63 +++------------ src/proxy.c | 33 +------- 7 files changed, 24 insertions(+), 278 deletions(-) delete mode 100644 reg-tests/connection/dispatch.vtc diff --git a/doc/configuration.txt b/doc/configuration.txt index 6e0eedb23..757399ba2 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -6160,7 +6160,6 @@ default-server X - X X default_backend X X X - description - X X X disabled X X X X -dispatch (deprecated) - - X X email-alert from X X X X email-alert level X X X X email-alert mailers X X X X @@ -6269,7 +6268,6 @@ option tcp-smart-accept (*) X X X - option tcp-smart-connect (*) X - X X option tcpka X X X X option tcplog X X X - -option transparent (deprecated) (*) X - X X option use-small-buffers (*) X - X X persist rdp-cookie X - X X quic-initial X (!) X X - @@ -6331,7 +6329,6 @@ timeout server X - X X timeout server-fin X - X X timeout tarpit X X X X timeout tunnel X - X X -transparent (deprecated) X - X X unique-id-format X X X X unique-id-header X X X - use_backend - X X - @@ -6746,7 +6743,7 @@ balance url_param [check_post] might be a URL parameter list. This is probably not a concern with SGML type message bodies. - See also : "dispatch", "cookie", "transparent", "hash-type". + See also : "cookie", "hash-type". bind [
]: [, ...] [param*] @@ -7527,54 +7524,6 @@ disabled See also : "enabled", "force-be-switch" -dispatch
: (deprecated) - Set a default server address - - May be used in the following contexts: tcp, http - - May be used in sections : defaults | frontend | listen | backend - no | no | yes | yes - - Arguments : - -
is the IPv4 address of the default server. Alternatively, a - resolvable hostname is supported, but this name will be resolved - during start-up. - - is a mandatory port specification. All connections will be sent - to this port, and it is not permitted to use port offsets as is - possible with normal servers. - - The "dispatch" keyword designates a default server for use when no other - server can take the connection. In the past it was used to forward non - persistent connections to an auxiliary load balancer. Due to its simple - syntax, it has also been used for simple TCP relays. It is recommended not to - use it for more clarity, and to use the "server" directive instead. - - This keyword has been deprecated in 3.3 and will be removed in 3.5 due to - some internal limitations (no support for SSL nor idle connections etc). - Using it will emit a warning that may be silenced by enabling directive - "expose-deprecated-directives" in the global section. - - The correct way to proceed without this directive is to simply declare a - server with the same address and port. If the "dispatch" directive was - mixed with other servers, then these servers should be configured with a - weight of zero in order never to be elected by the load balancing algorithm. - - Example: - backend deprecated_setup - dispatch 192.168.100.100:80 # external load balancer's address - server s1 192.168.100.1:80 cookie S1 check - server s2 192.168.100.2:80 cookie S2 check - - backend modern_setup - server external_lb 192.168.100.100:80 - server s1 192.168.100.1:80 cookie S1 check weight 0 - server s2 192.168.100.2:80 cookie S2 check weight 0 - - See also : "server" - - dynamic-cookie-key Set the dynamic cookie secret key for a backend. @@ -12137,46 +12086,6 @@ option tcplog [clf] See also : "option httplog", and section 8 about logging. -option transparent (deprecated) -no option transparent (deprecated) - Enable client-side transparent proxying - - May be used in the following contexts: tcp, http - - May be used in sections : defaults | frontend | listen | backend - yes | no | yes | yes - - Arguments : none - - This option was introduced in order to provide layer 7 persistence to layer 3 - load balancers. The idea is to use the OS's ability to redirect an incoming - connection for a remote address to a local process (here HAProxy), and let - this process know what address was initially requested. When this option is - used, sessions without cookies will be forwarded to the original destination - IP address of the incoming request (which should match that of another - equipment), while requests with cookies will still be forwarded to the - appropriate server. - - Note that contrary to a common belief, this option does NOT make HAProxy - present the client's IP to the server when establishing the connection. - - As of 3.3, this option is now deprecated because it used to suffer from a - number of internal technical limitations. Using it will emit a warning, which - can be avoided if really needed via the "expose-deprecated-directives" global - keyword. - - The correct approach is to declare a server on address 0.0.0.0, which will - take care of connecting to the expected destination address. A server will - also properly handle idle connections to the target servers. - - Example: - # option transparent ## before 3.3 - server transparent 0.0.0.0 - - See also: the "usesrc" argument of the "source" keyword, and the - "transparent" option of the "bind" keyword. - - option use-small-buffers [ queue | l7-retries | check ]* Enable support for small buffers for the given categories. @@ -12605,9 +12514,9 @@ server
[:[port]] [param*] address as the one from the client connection. This is useful in transparent proxy architectures where the client's connection is intercepted and HAProxy must forward to the original destination - address. This is more or less what the "transparent" keyword does - except that with a server it's possible to limit concurrency and - to report statistics. Optionally, an address family prefix may be + address. This is more or less what the old "transparent" keyword + did except that servers do not have the keyword's limitations + (ssl, queues etc). Optionally, an address family prefix may be used before the address to force the family regardless of the address format, which can be useful to specify a path to a unix socket with no slash ('/'). Currently supported prefixes are : @@ -15162,32 +15071,6 @@ timeout tunnel See also : "timeout client", "timeout client-fin", "timeout server". -transparent (deprecated) - Enable client-side transparent proxying - - May be used in the following contexts: tcp, http - - May be used in sections : defaults | frontend | listen | backend - yes | no | yes | yes - - Arguments : none - - This keyword was introduced in order to provide layer 7 persistence to layer - 3 load balancers. The idea is to use the OS's ability to redirect an incoming - connection for a remote address to a local process (here HAProxy), and let - this process know what address was initially requested. When this option is - used, sessions without cookies will be forwarded to the original destination - IP address of the incoming request (which should match that of another - equipment), while requests with cookies will still be forwarded to the - appropriate server. - - The "transparent" keyword is deprecated, use "option transparent" instead. - - Note that contrary to a common belief, this option does NOT make HAProxy - present the client's IP to the server when establishing the connection. - - See also: "option transparent" - unique-id-format Generate a unique ID for each request. diff --git a/doc/management.txt b/doc/management.txt index d155f8d5e..e0a331209 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -2148,8 +2148,7 @@ del backend There is additional restrictions which prevent backend removal. First, a backend cannot be removed if it is explicitly referenced by config elements, for example via a use_backend rule or in sample expressions. Some proxies - options are also incompatible with runtime deletion. Currently, this is the - case when deprecated dispatch or option transparent are used. Also, a backend + options are also incompatible with runtime deletion. Currently, a backend cannot be removed if there is a stick-table declared in it. Finally, it is impossible for now to remove a backend if QUIC servers were present in it. diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index acc84b647..365e891a2 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -79,7 +79,7 @@ enum PR_SRV_STATE_FILE { /* bits for proxy->options */ #define PR_O_REDISP 0x00000001 /* allow reconnection to dispatch in case of errors */ -#define PR_O_TRANSP 0x00000002 /* transparent mode : use original DEST as dispatch */ +/* unused: 0x00000002 */ /* HTTP server-side reuse */ #define PR_O_REUSE_NEVR 0x00000000 /* never reuse a shared connection */ @@ -90,7 +90,7 @@ enum PR_SRV_STATE_FILE { #define PR_O_IDLE_CLOSE_RESP 0x00000010 /* avoid closing idle connections during a soft stop */ #define PR_O_PREF_LAST 0x00000020 /* prefer last server */ -#define PR_O_DISPATCH 0x00000040 /* use dispatch mode */ +/* unused: 0x00000040 */ #define PR_O_FORCED_ID 0x00000080 /* proxy's ID was forced in the configuration */ /* unused: 0x00000100 */ #define PR_O_IGNORE_PRB 0x00000200 /* ignore empty requests (aborts and timeouts) */ @@ -327,7 +327,7 @@ struct proxy { unsigned int maxconn; /* max # of active streams on the frontend */ - int options; /* PR_O_REDISP, PR_O_TRANSP, ... */ + int options; /* PR_O_* */ int options2; /* PR_O2_* */ int options3; /* PR_O3_* */ unsigned int ck_opts; /* PR_CK_* (cookie options) */ @@ -458,11 +458,10 @@ struct proxy { unsigned int li_suspended; /* total number of listeners suspended (could be paused or unbound) */ /* warning: these structs are huge, keep them at the bottom */ - struct sockaddr_storage dispatch_addr; /* the default address to connect to */ struct error_snapshot *invalid_req, *invalid_rep; /* captures of last errors */ /* used only during configuration parsing */ - int no_options; /* PR_O_REDISP, PR_O_TRANSP, ... */ + int no_options; /* PR_O_* */ int no_options2; /* PR_O2_* */ int no_options3; /* PR_O3_* */ diff --git a/reg-tests/connection/dispatch.vtc b/reg-tests/connection/dispatch.vtc deleted file mode 100644 index 9bb9f88f4..000000000 --- a/reg-tests/connection/dispatch.vtc +++ /dev/null @@ -1,50 +0,0 @@ -varnishtest "Validate proper operation of the 'dispatch' mode" -feature ignore_unknown_macro - -server s1 { - rxreq - txresp -} -start - -server s2 { - rxreq - txresp -} -start - -haproxy h1 -conf { -global - .if feature(THREAD) - thread-groups 1 - .endif - - # this is needed since 3.3, and this test will be removed in 3.5. - expose-deprecated-directives - -defaults - log global - timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" - timeout client "${HAPROXY_TEST_TIMEOUT-5s}" - timeout server "${HAPROXY_TEST_TIMEOUT-5s}" - -listen fe_tcp - bind "fd@${fe_tcp}" - mode tcp - dispatch ${s1_addr}:${s1_port} - -listen fe_http - bind "fd@${fe_http}" - mode http - dispatch ${s2_addr}:${s2_port} -} -start - -client c1 -connect ${h1_fe_tcp_sock} { - txreq -url "/" - rxresp - expect resp.status == 200 -} -run - -client c2 -connect ${h1_fe_http_sock} { - txreq -url "/" - rxresp - expect resp.status == 200 -} -run diff --git a/src/backend.c b/src/backend.c index 726c88d60..efa90af98 100644 --- a/src/backend.c +++ b/src/backend.c @@ -854,9 +854,6 @@ int assign_server(struct stream *s) } stream_set_srv_target(s, srv); } - else if (s->be->options & (PR_O_DISPATCH | PR_O_TRANSP)) { - s->target = &s->be->obj_type; - } else { err = SRV_STATUS_NOSRV; goto out; @@ -951,22 +948,6 @@ static int alloc_dst_address(struct sockaddr_storage **ss, } } } - else if (s->be->options & PR_O_DISPATCH) { - if (!sockaddr_alloc(ss, NULL, 0)) - return SRV_STATUS_INTERNAL; - - /* connect to the defined dispatch addr */ - **ss = s->be->dispatch_addr; - } - else if ((s->be->options & PR_O_TRANSP)) { - if (!sockaddr_alloc(ss, NULL, 0)) - return SRV_STATUS_INTERNAL; - - /* in transparent mode, use the original dest addr if no dispatch specified */ - dst = sc_dst(s->scf); - if (dst && (dst->ss_family == AF_INET || dst->ss_family == AF_INET6)) - **ss = *dst; - } else { /* no server and no LB algorithm ! */ return SRV_STATUS_INTERNAL; diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index c467e12c4..ca5d3ad62 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -2621,22 +2621,13 @@ stats_error_parsing: goto out; } } -#ifdef USE_TPROXY else if (strcmp(args[0], "transparent") == 0) { - /* enable transparent proxy connections */ - curproxy->options |= PR_O_TRANSP; - if (alertif_too_many_args(0, file, linenum, args, &err_code)) - goto out; - if (!deprecated_directives_allowed) { - ha_warning("parsing [%s:%d]: '%s' is deprecated in 3.3 and will be removed in 3.5. " - "The modern way to do the same is to create a server with address 0.0.0.0. It is " - "still possible to silence this warning by setting 'expose-deprecated-directives' " - "in the 'global' section, but do not wait to fix your configuration!\n", - file, linenum, args[0]); - err_code |= ERR_WARN; - } + ha_alert("parsing [%s:%d]: support for '%s' was removed in version 3.5. " + "The modern way to do the same is to create a server with address 0.0.0.0.\n", + file, linenum, args[0]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; } -#endif else if (strcmp(args[0], "maxconn") == 0) { /* maxconn */ if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], " Maybe you want 'fullconn' instead ?")) err_code |= ERR_WARN; @@ -2683,43 +2674,13 @@ stats_error_parsing: goto out; } else if (strcmp(args[0], "dispatch") == 0) { /* dispatch address */ - struct sockaddr_storage *sk; - int port1, port2; - - if (curproxy->cap & PR_CAP_DEF) { - ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - else if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) - err_code |= ERR_WARN; - - sk = str2sa_range(args[1], NULL, &port1, &port2, NULL, 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); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - - if (alertif_too_many_args(1, file, linenum, args, &err_code)) - goto out; - - if (!deprecated_directives_allowed) { - ha_warning("parsing [%s:%d]: '%s' is deprecated in 3.3 and will be removed in 3.5. " - "The modern way to do the same is to create a server with the same address, and " - "possibly to assign any extra server a weight of zero if any:\n" - " server dispatch %s\n" - "Note that it is still possible to silence this warning by setting " - "'expose-deprecated-directives' in the 'global' section, but do not wait to fix " - "your configuration!\n", - file, linenum, args[0], args[1]); - err_code |= ERR_WARN; - } - - curproxy->dispatch_addr = *sk; - curproxy->options |= PR_O_DISPATCH; + ha_alert("parsing [%s:%d]: support for '%s' was removed in version 3.5. " + "The modern way to do the same is to create a server with the same address, and " + "possibly to assign any extra server a weight of zero if any:\n" + " server dispatch %s\n", + file, linenum, args[0], args[1]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; } else if (strcmp(args[0], "balance") == 0) { /* set balancing with optional algorithm */ if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) diff --git a/src/proxy.c b/src/proxy.c index 6b54a08ea..885ea679e 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -117,11 +117,7 @@ const struct cfg_opt cfg_opts[] = { "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0, 0 }, { "persist", PR_O_PERSIST, PR_CAP_BE, 0, 0 }, { "srvtcpka", PR_O_TCP_SRV_KA, PR_CAP_BE, 0, 0 }, -#ifdef USE_TPROXY - { "transparent", PR_O_TRANSP, PR_CAP_BE, 0, 0 }, -#else - { "transparent", 0, 0, 0, 0 }, -#endif + { "transparent", 0x305, 0, 0, 0 }, { NULL, 0, 0, 0, 0 } }; @@ -1879,21 +1875,8 @@ int proxy_finalize(struct proxy *px, int *err_code) } if (px->cap & PR_CAP_BE) { - if (px->lbprm.algo & BE_LB_KIND) { - if (px->options & PR_O_TRANSP) { - ha_alert("%s '%s' cannot use both transparent and balance mode.\n", - proxy_type_str(px), px->id); - cfgerr++; - } - else if (px->options & PR_O_DISPATCH) { - ha_warning("dispatch address of %s '%s' will be ignored in balance mode.\n", - proxy_type_str(px), px->id); - *err_code |= ERR_WARN; - } - } - else if (!(px->options & (PR_O_TRANSP | PR_O_DISPATCH))) { - /* If no LB algo is set in a backend, and we're not in - * transparent mode, dispatch mode nor proxy mode, we + if (!(px->lbprm.algo & BE_LB_KIND)) { + /* If no LB algo is set in a backend, we * want to use balance random by default. */ px->lbprm.algo &= ~BE_LB_ALGO; @@ -1901,11 +1884,6 @@ int proxy_finalize(struct proxy *px, int *err_code) } } - if (px->options & PR_O_DISPATCH) - px->options &= ~PR_O_TRANSP; - else if (px->options & PR_O_TRANSP) - px->options &= ~PR_O_DISPATCH; - if ((px->tcpcheck.flags & TCPCHK_FL_UNUSED_HTTP_RS)) { ha_warning("%s '%s' uses http-check rules without 'option httpchk', so the rules are ignored.\n", proxy_type_str(px), px->id); @@ -5041,11 +5019,6 @@ int be_check_for_deletion(const char *bename, struct proxy **pb, const char **pm goto out; } - if (be->options & (PR_O_DISPATCH|PR_O_TRANSP)) { - msg = "Deletion of backend with deprecated dispatch/transparent options is not supported."; - goto out; - } - if (be->table) { msg = "Cannot remove a backend with stick-table."; goto out;