BUG/MINOR: only auto-prefer last server if lb-alg is non-deterministic

While "option prefer-last-server" only applies to non-deterministic load
balancing algorithms, 401/407 responses actually caused haproxy to prefer
the last server unconditionally.

As this breaks deterministic load balancing algorithms like uri, this
patch applies the same condition here.

Should be backported to 1.8 (together with "BUG/MINOR: only mark
connections private if NTLM is detected").
This commit is contained in:
Lukas Tribus 2018-10-27 20:07:40 +02:00 committed by Willy Tarreau
parent fd9b68c48e
commit 80512b186f
3 changed files with 11 additions and 4 deletions

View File

@ -2512,6 +2512,11 @@ balance url_param <param> [check_post]
algorithm, mode nor option have been set. The algorithm may only be set once algorithm, mode nor option have been set. The algorithm may only be set once
for each backend. for each backend.
With authentication schemes that require the same connection like NTLM, URI
based alghoritms must not be used, as they would cause subsequent requests
to be routed to different backend servers, breaking the invalid assumptions
NTLM relies on.
Examples : Examples :
balance roundrobin balance roundrobin
balance url_param userid balance url_param userid
@ -6537,8 +6542,9 @@ no option prefer-last-server
close of the connection. This can make sense for static file servers. It does close of the connection. This can make sense for static file servers. It does
not make much sense to use this in combination with hashing algorithms. Note, not make much sense to use this in combination with hashing algorithms. Note,
haproxy already automatically tries to stick to a server which sends a 401 or haproxy already automatically tries to stick to a server which sends a 401 or
to a proxy which sends a 407 (authentication required). This is mandatory for to a proxy which sends a 407 (authentication required), when the load
use with the broken NTLM authentication challenge, and significantly helps in balancing algorithm is not deterministic. This is mandatory for use with the
broken NTLM authentication challenge, and significantly helps in
troubleshooting some faulty applications. Option prefer-last-server might be troubleshooting some faulty applications. Option prefer-last-server might be
desirable in these environments as well, to avoid redistributing the traffic desirable in these environments as well, to avoid redistributing the traffic
after every other response. after every other response.

View File

@ -588,9 +588,9 @@ int assign_server(struct stream *s)
if (conn && if (conn &&
(conn->flags & CO_FL_CONNECTED) && (conn->flags & CO_FL_CONNECTED) &&
objt_server(conn->target) && __objt_server(conn->target)->proxy == s->be && objt_server(conn->target) && __objt_server(conn->target)->proxy == s->be &&
(s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI &&
((s->txn && s->txn->flags & TX_PREFER_LAST) || ((s->txn && s->txn->flags & TX_PREFER_LAST) ||
((s->be->options & PR_O_PREF_LAST) && ((s->be->options & PR_O_PREF_LAST) &&
(s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI &&
(!s->be->max_ka_queue || (!s->be->max_ka_queue ||
server_has_room(__objt_server(conn->target)) || server_has_room(__objt_server(conn->target)) ||
(__objt_server(conn->target)->nbpend + 1) < s->be->max_ka_queue))) && (__objt_server(conn->target)->nbpend + 1) < s->be->max_ka_queue))) &&

View File

@ -3712,7 +3712,8 @@ void http_end_txn_clean_session(struct stream *s)
* server over the same connection. This is required by some * server over the same connection. This is required by some
* broken protocols such as NTLM, and anyway whenever there is * broken protocols such as NTLM, and anyway whenever there is
* an opportunity for sending the challenge to the proper place, * an opportunity for sending the challenge to the proper place,
* it's better to do it (at least it helps with debugging). * it's better to do it (at least it helps with debugging), at
* least for non-deterministic load balancing algorithms.
*/ */
s->txn->flags |= TX_PREFER_LAST; s->txn->flags |= TX_PREFER_LAST;
} }