haproxy/contrib
Willy Tarreau c192b0ab95 MEDIUM: connection: remove CO_FL_CONNECTED and only rely on CO_FL_WAIT_*
Commit 477902bd2e ("MEDIUM: connections: Get ride of the xprt_done
callback.") broke the master CLI for a very obscure reason. It happens
that short requests immediately terminated by a shutdown are properly
received, CS_FL_EOS is correctly set, but in si_cs_recv(), we refrain
from setting CF_SHUTR on the channel because CO_FL_CONNECTED was not
yet set on the connection since we've not passed again through
conn_fd_handler() and it was not done in conn_complete_session(). While
commit a8a415d31a ("BUG/MEDIUM: connections: Set CO_FL_CONNECTED in
conn_complete_session()") fixed the issue, such accident may happen
again as the root cause is deeper and actually comes down to the fact
that CO_FL_CONNECTED is lazily set at various check points in the code
but not every time we drop one wait bit. It is not the first time we
face this situation.

Originally this flag was used to detect the transition between WAIT_*
and CONNECTED in order to call ->wake() from the FD handler. But since
at least 1.8-dev1 with commit 7bf3fa3c23 ("BUG/MAJOR: connection: update
CO_FL_CONNECTED before calling the data layer"), CO_FL_CONNECTED is
always synchronized against the two others before being checked. Moreover,
with the I/Os moved to tasklets, the decision to call the ->wake() function
is performed after the I/Os in si_cs_process() and equivalent, which don't
care about this transition either.

So in essence, checking for CO_FL_CONNECTED has become a lazy wait to
check for (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN), but that always
relies on someone else having synchronized it.

This patch addresses it once for all by killing this flag and only checking
the two others (for which a composite mask CO_FL_WAIT_L4L6 was added). This
revealed a number of inconsistencies that were purposely not addressed here
for the sake of bisectability:

  - while most places do check both L4+L6 and HANDSHAKE at the same time,
    some places like assign_server() or back_handle_st_con() and a few
    sample fetches looking for proxy protocol do check for L4+L6 but
    don't care about HANDSHAKE ; these ones will probably fail on TCP
    request session rules if the handshake is not complete.

  - some handshake handlers do validate that a connection is established
    at L4 but didn't clear CO_FL_WAIT_L4_CONN

  - the ->ctl method of mux_fcgi, mux_pt and mux_h1 only checks for L4+L6
    before declaring the mux ready while the snd_buf function also checks
    for the handshake's completion. Likely the former should validate the
    handshake as well and we should get rid of these extra tests in snd_buf.

  - raw_sock_from_buf() would directly set CO_FL_CONNECTED and would only
    later clear CO_FL_WAIT_L4_CONN.

  - xprt_handshake would set CO_FL_CONNECTED itself without actually
    clearing CO_FL_WAIT_L4_CONN, which could apparently happen only if
    waiting for a pure Rx handshake.

  - most places in ssl_sock that were checking CO_FL_CONNECTED don't need
    to include the L4 check as an L6 check is enough to decide whether to
    wait for more info or not.

It also becomes obvious when reading the test in si_cs_recv() that caused
the failure mentioned above that once converted it doesn't make any sense
anymore: having CS_FL_EOS set while still waiting for L4 and L6 to complete
cannot happen since for CS_FL_EOS to be set, the other ones must have been
validated.

Some of these parts will still deserve further cleanup, and some of the
observations above may induce some backports of potential bug fixes once
totally analyzed in their context. The risk of breaking existing stuff
is too high to blindly backport everything.
2020-01-23 14:41:37 +01:00
..
51d/src BUILD/MINOR: 51d: Updated build registration output to indicate thatif the library is a dummy one or not. 2019-06-13 18:00:54 +02:00
base64
debug MEDIUM: connection: remove CO_FL_CONNECTED and only rely on CO_FL_WAIT_* 2020-01-23 14:41:37 +01:00
deviceatlas BUILD: contrib/da: remove an "unused" warning 2019-11-15 13:39:16 +01:00
halog CLEANUP: fix a typo in a comment for the contrib/halog subsystem 2018-11-12 08:52:16 +01:00
hpack BUILD: use inttypes.h instead of stdint.h 2019-04-01 07:44:56 +02:00
ip6range BUILD: contrib: fix ip6range build on Centos 7 2016-11-22 11:50:51 +01:00
iprange CONTRIB: iprange: Fix compiler warning in iprange.c 2017-12-20 09:36:58 +01:00
mod_defender MAJOR: chunks: replace struct chunk with struct buffer 2018-07-19 16:23:43 +02:00
modsecurity MAJOR: http: Remove the HTTP legacy code 2019-07-19 09:24:12 +02:00
netsnmp-perl
plug_qdisc BUILD: use inttypes.h instead of stdint.h 2019-04-01 07:44:56 +02:00
prometheus-exporter MINOR: counters: Remove failed_secu counter and use denied_resp instead 2020-01-20 15:18:45 +01:00
selinux
spoa_example BUILD: use inttypes.h instead of stdint.h 2019-04-01 07:44:56 +02:00
spoa_server DOC: contrib: spoa_server Add some hints for building spoa_server 2019-07-05 16:31:50 +02:00
syntax-highlight MEDIUM: Make '(cli|con|srv)timeout' directive fatal 2019-06-17 13:35:54 +02:00
systemd MINOR: systemd: support /etc/sysconfig/ for redhat based distrib 2019-05-07 14:11:55 +02:00
tcploop CONTRIB: tcploop: add action "X" to execute a command 2017-05-03 06:58:53 +02:00
trace CONTRIB: trace: report the base name only for file names 2017-10-24 19:54:25 +02:00
wireshark-dissectors/peers BUILD: use inttypes.h instead of stdint.h 2019-04-01 07:44:56 +02:00
wurfl CONTRIB: wurfl: address 3 build issues in the wurfl dummy library 2019-05-22 14:59:08 +02:00