|
|
- commit 489bbd321e46c110ab9d92fb91725870d7c40491
- Author: Willy Tarreau <w@1wt.eu>
- Date: Tue Sep 24 10:43:03 2019 +0200
-
- BUG/MEDIUM: checks: make sure the connection is ready before trying to recv
-
- As identified in issue #278, the backport of commit c594039225 ("BUG/MINOR:
- checks: do not uselessly poll for reads before the connection is up")
- introduced a regression in 2.0 when default checks are enabled (not
- "option tcp-check"), but it did not affect 2.1.
-
- What happens is that in 2.0 and earlier we have the fd cache which makes
- a speculative call to the I/O functions after an attempt to connect, and
- the __event_srv_chk_r() function was absolutely not designed to be called
- while a connection attempt is still pending. Thus what happens is that the
- test for success/failure expects the verdict to be final before waking up
- the check task, and since the connection is not yet validated, it fails.
- It will usually work over the loopback depending on scheduling, which is
- why it doesn't fail in reg tests.
-
- In 2.1 after the failed connect(), we subscribe to polling and usually come
- back with a validated connection, so the function is not expected to be
- called before it completes, except if it happens as a side effect of some
- spurious wake calls, which should not have any effect on such a check.
-
- The other check types are not impacted by this issue because they all
- check for a minimum data length in the buffer, and wait for more data
- until they are satisfied.
-
- This patch fixes the issue by explicitly checking that the connection
- is established before trying to read or to give a verdict. This way the
- function becomes safe to call regardless of the connection status (even
- if it's still totally ugly).
-
- This fix must be backported to 2.0.
-
- (cherry picked from commit 0f0393fc0d2badc5ea329844691f06ba28827f78)
- Signed-off-by: Willy Tarreau <w@1wt.eu>
-
- diff --git a/src/checks.c b/src/checks.c
- index b088da2e..06f47ad9 100644
- --- a/src/checks.c
- +++ b/src/checks.c
- @@ -875,6 +875,9 @@ static void __event_srv_chk_r(struct conn_stream *cs)
- }
- }
-
- + /* the rest of the code below expects the connection to be ready! */
- + if (!(conn->flags & CO_FL_CONNECTED) && !done)
- + goto wait_more_data;
-
- /* Intermediate or complete response received.
- * Terminate string in b_head(&check->bi) buffer.
|