Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BUG/MEDIUM: http_ana: ignore NTLM for reuse aggressive/always and no H1
Backend connections can be marked as private to prevent their sharing by multiple clients. Now, this has become an exception as only two reasons for data traffic can trigger this (checks are ignored here) : * http-reuse never * HTTP response with NTLM header The first case is easy to manage as the connection is flagged as private since its inception. However, the second case is dynamic as the connection can be flagged anytime during its lifetime. When using a backend protocol such as HTTP/2 with reuse mode aggressive or always, we face a design issue as the connection would be marked as private, despite potentially being shared by several clients at the same time. This is conceptually invalid, but worst it can trigger crashes on MUX stream detach callback depending on the order of release of the streams, by calling session_check_idle_conn() with a NULL session. It could also be possible to have several NTLM responses on a single connection for different sessions. In this case, connection owner is still being updated without attaching the connection to its correct session, which ultimately would cause a crash on session_check_idle_conn with an invalid session. Here are two backtrace examples from GDB for such cases : Thread 1 (Thread 0x7ff73e9fc700 (LWP 648859)): #0 session_check_idle_conn (conn=0x7ff72f597800, sess=0x0) at include/haproxy/session.h:209 joyent#1 h2_detach (sd=<optimized out>) at src/mux_h2.c:4520 joyent#2 0x000056151742be24 in sc_detach_endp (scp=scp@entry=0x7ff73e9f0f18) at src/stconn.c:376 haproxy#3 0x000056151742c208 in sc_destroy (sc=<optimized out>) at src/stconn.c:444 haproxy#4 0x0000561517370871 in stream_free (s=s@entry=0x7ff72a2dbd80) at src/stream.c:728 haproxy#5 0x000056151737541f in process_stream (t=t@entry=0x7ff72d5e2620, context=0x7ff72a2dbd80, state=<optimized out>) at src/stream.c:2645 haproxy#6 0x0000561517456cbb in run_tasks_from_lists (budgets=budgets@entry=0x7ff73e9f10d0) at src/task.c:632 haproxy#7 0x00005615174576b9 in process_runnable_tasks () at src/task.c:876 haproxy#8 0x000056151742275a in run_poll_loop () at src/haproxy.c:2996 haproxy#9 0x0000561517422db1 in run_thread_poll_loop (data=<optimized out>) at src/haproxy.c:3195 haproxy#10 0x00007ff789e081ca in start_thread () from /lib64/libpthread.so.0 haproxy#11 0x00007ff789a39e73 in clone () from /lib64/libc.so.6 (gdb) Thread 1 (Thread 0x7ff52e7fc700 (LWP 681458)): #0 0x0000556ebd6e7e69 in session_check_idle_conn (conn=0x7ff5787ff100, sess=0x7ff51d2539a0) at include/haproxy/session.h:209 joyent#1 h2_detach (sd=<optimized out>) at src/mux_h2.c:4520 joyent#2 0x0000556ebd7f3e24 in sc_detach_endp (scp=scp@entry=0x7ff52e7f0f18) at src/stconn.c:376 haproxy#3 0x0000556ebd7f4208 in sc_destroy (sc=<optimized out>) at src/stconn.c:444 haproxy#4 0x0000556ebd738871 in stream_free (s=s@entry=0x7ff520e28200) at src/stream.c:728 haproxy#5 0x0000556ebd73d41f in process_stream (t=t@entry=0x7ff565783700, context=0x7ff520e28200, state=<optimized out>) at src/stream.c:2645 haproxy#6 0x0000556ebd81ecbb in run_tasks_from_lists (budgets=budgets@entry=0x7ff52e7f10d0) at src/task.c:632 haproxy#7 0x0000556ebd81f6b9 in process_runnable_tasks () at src/task.c:876 haproxy#8 0x0000556ebd7ea75a in run_poll_loop () at src/haproxy.c:2996 haproxy#9 0x0000556ebd7eadb1 in run_thread_poll_loop (data=<optimized out>) at src/haproxy.c:3195 haproxy#10 0x00007ff5752081ca in start_thread () from /lib64/libpthread.so.0 haproxy#11 0x00007ff574e39e73 in clone () from /lib64/libc.so.6 (gdb) To solve this issue, simply ignore NTLM responses when using a multiplexer with streams support and the connection is not already attached to the session. The connection is not marked as private and will continue to be shared freely accross clients. This is considered conceptually valid as NTLM usage (rfc 4559) with HTTP is broken and was designed only with HTTP/1.1 in mind. A side-effect of the change is that SESS_FL_PREFER_LAST is also not set anymore on NTLM detection, which allows following requests to be load-balanced accross several server instances. The original behavior is kept for HTTP/1 or if the connection is already attached to the session. This last case happens when using HTTP/2 with default http-reuse safe mode since the following patch : 0d21dea MEDIUM: backend: add reused conn to sess if mux marked as HOL blocking This should be backported up to all stable releases. Up until 2.4, it can be taken as-is. For lesser versions, above patch is not present. In this case the condition should be restricted only to HTTP/1 usage : if (srv_conn && strcmp(srv_conn->mux->name, "H1") == 0) {
- Loading branch information