mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-09 16:47:18 +02:00
BUG/MINOR: checks: Handle synchronous connect when a tcpcheck is started
A connection may be synchronously established. In the tcpcheck context, it may be a problem if several connections come one after another. In this case, there is no event to close the very first connection before starting the next one. The checks is thus blocked and timed out, a L7 timeout error is reported. To fix the bug, when a tcpcheck is started, we immediately evaluate its state. Most of time, nothing is performed and we must wait. But it is thus possible to handle the result of a successfull connection. This patch should fix the issue #1234. It must be backported as far as 2.2.
This commit is contained in:
parent
30aa0da532
commit
92017a3215
15
src/check.c
15
src/check.c
@ -1092,8 +1092,8 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
|
||||
{
|
||||
struct check *check = context;
|
||||
struct proxy *proxy = check->proxy;
|
||||
struct conn_stream *cs = check->cs;
|
||||
struct connection *conn = cs_conn(cs);
|
||||
struct conn_stream *cs;
|
||||
struct connection *conn;
|
||||
int rv;
|
||||
int expired = tick_is_expired(t->expire, now_ms);
|
||||
|
||||
@ -1101,6 +1101,7 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
|
||||
|
||||
if (check->server)
|
||||
HA_SPIN_LOCK(SERVER_LOCK, &check->server->lock);
|
||||
|
||||
if (!(check->state & CHK_ST_INPROGRESS)) {
|
||||
/* no check currently running */
|
||||
if (!expired) /* woke up too early */ {
|
||||
@ -1128,9 +1129,12 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
|
||||
|
||||
check->current_step = NULL;
|
||||
tcpcheck_main(check);
|
||||
goto out_unlock;
|
||||
expired = 0;
|
||||
}
|
||||
else {
|
||||
|
||||
cs = check->cs;
|
||||
conn = cs_conn(cs);
|
||||
|
||||
/* there was a test running.
|
||||
* First, let's check whether there was an uncaught error,
|
||||
* which can happen on connect timeout or error.
|
||||
@ -1139,7 +1143,7 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
|
||||
/* Here the connection must be defined. Otherwise the
|
||||
* error would have already been detected
|
||||
*/
|
||||
if ((conn->flags & CO_FL_ERROR) || cs->flags & CS_FL_ERROR || expired) {
|
||||
if ((conn && ((conn->flags & CO_FL_ERROR) || (cs->flags & CS_FL_ERROR))) || expired) {
|
||||
TRACE_ERROR("report connection error", CHK_EV_TASK_WAKE|CHK_EV_HCHK_END|CHK_EV_HCHK_ERR, check);
|
||||
chk_report_conn_err(check, 0, expired);
|
||||
}
|
||||
@ -1223,7 +1227,6 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
|
||||
}
|
||||
t->expire = tick_add(now_ms, MS_TO_TICKS(srv_getinter(check) + rv));
|
||||
}
|
||||
}
|
||||
|
||||
reschedule:
|
||||
while (tick_is_expired(t->expire, now_ms))
|
||||
|
Loading…
Reference in New Issue
Block a user