mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-24 23:31:40 +02:00
BUG/MEDIUM: tcp-check: properly indicate polling state before performing I/O
While porting the connection to use the mux layer, it appeared that tcp-checks wouldn't receive anymore because the polling is not enabled before attempting to call xprt->rcv_buf() nor xprt->snd_buf(), and it is illegal to call these functions with polling disabled as they directly manipulate the FD state, resulting in an inconsistency where the FD is enabled and the connection's polling flags disabled. Till now it happened to work only because when recv() fails on EAGAIN it calls fd_cant_recv() which enables polling while signaling the failure, so that next time the message is received. But the connection's polling is never enabled, and any tiny change resulting in a call to conn_data_update_polling() immediately disables reading again. It's likely that this problem already happens on some corner cases such as multi-packet responses. It definitely breaks as soon as the response buffer is full but we don't support consuming more than one response buffer. This fix should be backported to 1.7 and 1.6. In order to check for the proper behaviour, this tcp-check must work and clearly show an SSH banner in recvfrom() as observed under strace, otherwise it's broken : tcp-check connect port 22 tcp-check expect rstring SSH tcp-check send blah
This commit is contained in:
parent
3cad394520
commit
a3782e7594
@ -2591,6 +2591,7 @@ static void tcpcheck_main(struct connection *conn)
|
|||||||
check->current_step->action != TCPCHK_ACT_SEND ||
|
check->current_step->action != TCPCHK_ACT_SEND ||
|
||||||
check->current_step->string_len >= buffer_total_space(check->bo))) {
|
check->current_step->string_len >= buffer_total_space(check->bo))) {
|
||||||
|
|
||||||
|
__conn_data_want_send(conn);
|
||||||
if (conn->xprt->snd_buf(conn, check->bo, 0) <= 0) {
|
if (conn->xprt->snd_buf(conn, check->bo, 0) <= 0) {
|
||||||
if (conn->flags & CO_FL_ERROR) {
|
if (conn->flags & CO_FL_ERROR) {
|
||||||
chk_report_conn_err(conn, errno, 0);
|
chk_report_conn_err(conn, errno, 0);
|
||||||
@ -2792,6 +2793,7 @@ static void tcpcheck_main(struct connection *conn)
|
|||||||
if (unlikely(check->result == CHK_RES_FAILED))
|
if (unlikely(check->result == CHK_RES_FAILED))
|
||||||
goto out_end_tcpcheck;
|
goto out_end_tcpcheck;
|
||||||
|
|
||||||
|
__conn_data_want_recv(conn);
|
||||||
if (conn->xprt->rcv_buf(conn, check->bi, check->bi->size) <= 0) {
|
if (conn->xprt->rcv_buf(conn, check->bi, check->bi->size) <= 0) {
|
||||||
if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH)) {
|
if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH)) {
|
||||||
done = 1;
|
done = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user