From 107a7326df4688b95bed691802bcf65fd9dff8ec Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Wed, 29 May 2019 15:01:50 +0200 Subject: [PATCH] MEDIUM: sessions: Introduce session flags. Add session flags, and add a new flag, SESS_FL_PREFER_LAST, to be set when we use NTLM authentication, and we should reuse the last connection. This should fix using NTLM with HTX. This totally replaces TX_PREFER_LAST. This should be backported to 1.9. (cherry picked from commit 250031e44412e3c6dd74995aba3fec783530eed0) Signed-off-by: Willy Tarreau --- contrib/debug/flags.c | 1 - include/types/proto_http.h | 2 +- include/types/session.h | 7 +++++++ src/backend.c | 4 ++-- src/proto_http.c | 2 +- src/proto_htx.c | 4 +++- src/session.c | 1 + 7 files changed, 15 insertions(+), 6 deletions(-) diff --git a/contrib/debug/flags.c b/contrib/debug/flags.c index c1a804742..986f8cfe2 100644 --- a/contrib/debug/flags.c +++ b/contrib/debug/flags.c @@ -275,7 +275,6 @@ void show_txn_flags(unsigned int f) SHOW_FLAG(f, TX_HDR_CONN_PRS); SHOW_FLAG(f, TX_WAIT_NEXT_RQ); SHOW_FLAG(f, TX_HDR_CONN_UPG); - SHOW_FLAG(f, TX_PREFER_LAST); SHOW_FLAG(f, TX_CON_KAL_SET); SHOW_FLAG(f, TX_CON_CLO_SET); diff --git a/include/types/proto_http.h b/include/types/proto_http.h index 8fc0feb90..d4fa652c1 100644 --- a/include/types/proto_http.h +++ b/include/types/proto_http.h @@ -94,7 +94,7 @@ #define TX_CON_CLO_SET 0x00400000 /* "connection: close" is now set */ #define TX_CON_KAL_SET 0x00800000 /* "connection: keep-alive" is now set */ -#define TX_PREFER_LAST 0x01000000 /* try to stay on same server if possible (eg: after 401) */ +/* unused: 0x01000000 */ #define TX_HDR_CONN_UPG 0x02000000 /* The "Upgrade" token was found in the "Connection" header */ #define TX_WAIT_NEXT_RQ 0x04000000 /* waiting for the second request to start, use keep-alive timeout */ diff --git a/include/types/session.h b/include/types/session.h index 328372d6e..824799a51 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -45,6 +45,12 @@ struct sess_srv_list { #define MAX_SRV_LIST 5 +/* session flags */ +enum { + SESS_FL_NONE = 0x00000000, /* nothing */ + SESS_FL_PREFER_LAST = 0x00000001, /* NTML authent, we should reuse last conn */ +}; + struct session { struct proxy *fe; /* the proxy this session depends on for the client side */ struct listener *listener; /* the listener by which the request arrived */ @@ -57,6 +63,7 @@ struct session { long t_handshake; /* handshake duration, -1 = not completed */ int idle_conns; /* Number of connections we're currently responsible for that we are not using */ struct list srv_list; /* List of servers and the connections the session is currently responsible for */ + unsigned int flags; /* session flags, SESS_FL_* */ }; #endif /* _TYPES_SESSION_H */ diff --git a/src/backend.c b/src/backend.c index d634e4a5f..0b603ec46 100644 --- a/src/backend.c +++ b/src/backend.c @@ -633,14 +633,14 @@ int assign_server(struct stream *s) s->target = NULL; if ((s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI && - ((s->txn && s->txn->flags & TX_PREFER_LAST) || + ((s->sess->flags & SESS_FL_PREFER_LAST) || (s->be->options & PR_O_PREF_LAST))) { struct sess_srv_list *srv_list; list_for_each_entry(srv_list, &s->sess->srv_list, srv_list) { struct server *tmpsrv = objt_server(srv_list->target); if (tmpsrv && tmpsrv->proxy == s->be && - ((s->txn && s->txn->flags & TX_PREFER_LAST) || + ((s->sess->flags & SESS_FL_PREFER_LAST) || (!s->be->max_ka_queue || server_has_room(tmpsrv) || ( tmpsrv->nbpend + 1 < s->be->max_ka_queue))) && diff --git a/src/proto_http.c b/src/proto_http.c index 56a876352..01ae97781 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -3539,7 +3539,7 @@ void http_end_txn_clean_session(struct stream *s) * 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->sess->flags |= SESS_FL_PREFER_LAST; } /* Never ever allow to reuse a connection from a non-reuse backend */ diff --git a/src/proto_htx.c b/src/proto_htx.c index b4855c051..4188e8495 100644 --- a/src/proto_htx.c +++ b/src/proto_htx.c @@ -1735,8 +1735,10 @@ int htx_wait_for_response(struct stream *s, struct channel *rep, int an_bit) ctx.blk = NULL; while (http_find_header(htx, hdr, &ctx, 0)) { if ((ctx.value.len >= 9 && word_match(ctx.value.ptr, ctx.value.len, "Negotiate", 9)) || - (ctx.value.len >= 4 && word_match(ctx.value.ptr, ctx.value.len, "NTLM", 4))) + (ctx.value.len >= 4 && word_match(ctx.value.ptr, ctx.value.len, "NTLM", 4))) { + sess->flags |= SESS_FL_PREFER_LAST; srv_conn->flags |= CO_FL_PRIVATE; + } } } diff --git a/src/session.c b/src/session.c index 58317b897..9abf662a6 100644 --- a/src/session.c +++ b/src/session.c @@ -59,6 +59,7 @@ struct session *session_new(struct proxy *fe, struct listener *li, enum obj_type HA_ATOMIC_ADD(&jobs, 1); LIST_INIT(&sess->srv_list); sess->idle_conns = 0; + sess->flags = SESS_FL_NONE; } return sess; }