if (conn && (!errno || errno == EAGAIN))
retrieve_errno_from_socket(conn);
- if (conn && !(conn->flags & CO_FL_ERROR) && !expired)
+ if (conn && !(conn->flags & CO_FL_ERROR) &&
+ !(cs->flags & CS_FL_ERROR) && !expired)
return;
/* we'll try to build a meaningful error message depending on the
}
else if ((conn->flags & (CO_FL_CONNECTED|CO_FL_WAIT_L4_CONN)) == CO_FL_WAIT_L4_CONN) {
/* L4 not established (yet) */
- if (conn->flags & CO_FL_ERROR)
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
set_server_check_status(check, HCHK_STATUS_L4CON, err_msg);
else if (expired)
set_server_check_status(check, HCHK_STATUS_L4TOUT, err_msg);
}
else if ((conn->flags & (CO_FL_CONNECTED|CO_FL_WAIT_L6_CONN)) == CO_FL_WAIT_L6_CONN) {
/* L6 not established (yet) */
- if (conn->flags & CO_FL_ERROR)
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
set_server_check_status(check, HCHK_STATUS_L6RSP, err_msg);
else if (expired)
set_server_check_status(check, HCHK_STATUS_L6TOUT, err_msg);
}
- else if (conn->flags & CO_FL_ERROR) {
+ else if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) {
/* I/O error after connection was established and before we could diagnose */
set_server_check_status(check, HCHK_STATUS_SOCKERR, err_msg);
}
if (check->bo->o) {
conn->mux->snd_buf(cs, check->bo, 0);
- if (conn->flags & CO_FL_ERROR) {
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) {
chk_report_conn_err(check, errno, 0);
__cs_stop_both(cs);
goto out_wakeup;
done = 0;
conn->mux->rcv_buf(cs, check->bi, check->bi->size);
- if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH)) {
+ if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH) || cs->flags & CS_FL_ERROR) {
done = 1;
- if ((conn->flags & CO_FL_ERROR) && !check->bi->i) {
+ if ((conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) && !check->bi->i) {
/* Report network errors only if we got no other data. Otherwise
* we'll let the upper layers decide whether the response is OK
* or not. It is very common that an RST sent by the server is
SPIN_UNLOCK(SERVER_LOCK, &check->server->lock);
out_wakeup:
/* collect possible new errors */
- if (conn->flags & CO_FL_ERROR)
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
chk_report_conn_err(check, 0, 0);
/* Reset the check buffer... */
conn = cs_conn(cs);
}
- if (unlikely(conn->flags & CO_FL_ERROR)) {
+ if (unlikely(conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)) {
/* We may get error reports bypassing the I/O handlers, typically
* the case when sending a pure TCP check which fails, then the I/O
* handlers above are not called. This is completely handled by the
else
set_server_check_status(check, HCHK_STATUS_L4OK, NULL);
}
- else if ((conn->flags & CO_FL_ERROR) || expired) {
+ else if ((conn->flags & CO_FL_ERROR) || cs->flags & CS_FL_ERROR || expired) {
chk_report_conn_err(check, 0, expired);
}
else
__cs_want_send(cs);
if (conn->mux->snd_buf(cs, check->bo, 0) <= 0) {
- if (conn->flags & CO_FL_ERROR) {
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) {
chk_report_conn_err(check, errno, 0);
__cs_stop_both(cs);
goto out_end_tcpcheck;
__cs_want_recv(cs);
if (conn->mux->rcv_buf(cs, 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) || cs->flags & CS_FL_ERROR) {
done = 1;
- if ((conn->flags & CO_FL_ERROR) && !check->bi->i) {
+ if ((conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) && !check->bi->i) {
/* Report network errors only if we got no other data. Otherwise
* we'll let the upper layers decide whether the response is OK
* or not. It is very common that an RST sent by the server is
out_end_tcpcheck:
/* collect possible new errors */
- if (conn->flags & CO_FL_ERROR)
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
chk_report_conn_err(check, 0, 0);
/* cleanup before leaving */
{
struct conn_stream *cs = conn->mux_ctx;
+ if (conn->flags & CO_FL_ERROR)
+ cs->flags |= CS_FL_ERROR;
if (conn_xprt_read0_pending(conn))
cs->flags |= CS_FL_EOS;
cs->data_cb->recv(cs);
{
struct conn_stream *cs = conn->mux_ctx;
+ if (conn->flags & CO_FL_ERROR)
+ cs->flags |= CS_FL_ERROR;
cs->data_cb->send(cs);
cs_update_mux_polling(cs);
}
ret = cs->conn->xprt->rcv_buf(cs->conn, buf, count);
if (conn_xprt_read0_pending(cs->conn))
cs->flags |= CS_FL_EOS;
+ if (cs->conn->flags & CO_FL_ERROR)
+ cs->flags |= CS_FL_ERROR;
return (ret);
}
ret = cs->conn->xprt->rcv_pipe(cs->conn, pipe, count);
if (conn_xprt_read0_pending(cs->conn))
cs->flags |= CS_FL_EOS;
+ if (cs->conn->flags & CO_FL_ERROR)
+ cs->flags |= CS_FL_ERROR;
return (ret);
}
if (!conn_ctrl_ready(conn))
return 0;
- if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH)) {
+ if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH) || cs->flags & CS_FL_ERROR) {
/* warning, we can't do anything on <conn> after this call ! */
si_release_endpoint(si);
return -1;
/* First step, report to the stream-int what was detected at the
* connection layer : errors and connection establishment.
*/
- if (conn->flags & CO_FL_ERROR)
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
si->flags |= SI_FL_ERR;
/* If we had early data, and the handshake ended, then
oc->pipe = NULL;
}
- if (conn->flags & CO_FL_ERROR)
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
return;
}
/* when we're here, we already know that there is no spliced
* data left, and that there are sendable buffered data.
*/
- if (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_WR_SH | CO_FL_HANDSHAKE)) && !(oc->flags & CF_SHUTW)) {
+ if (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_WR_SH | CO_FL_HANDSHAKE)) &&
+ !(cs->flags & CS_FL_ERROR) && !(oc->flags & CF_SHUTW)) {
/* check if we want to inform the kernel that we're interested in
* sending more data after this call. We want this if :
* - we're about to close after this last send and want to merge
__cs_want_send(cs);
si_cs_send(cs);
- if (cs->conn->flags & CO_FL_ERROR) {
+ if (cs->flags & CS_FL_ERROR || cs->conn->flags & CO_FL_ERROR) {
/* Write error on the file descriptor */
__cs_stop_both(cs);
si->flags |= SI_FL_ERR;
* happens when we send too large a request to a backend server
* which rejects it before reading it all.
*/
- if (conn->flags & CO_FL_ERROR)
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
return;
/* maybe we were called immediately after an asynchronous shutr */
if (cs->flags & CS_FL_EOS)
goto out_shutdown_r;
- if (conn->flags & CO_FL_ERROR)
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
return;
if (conn->flags & CO_FL_WAIT_ROOM) {
* that if such an event is not handled above in splice, it will be handled here by
* recv().
*/
- while (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_WAIT_ROOM | CO_FL_HANDSHAKE)) && !(ic->flags & CF_SHUTR)) {
+ while (!(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_WAIT_ROOM | CO_FL_HANDSHAKE)) &&
+ !(cs->flags & CS_FL_ERROR) && !(ic->flags & CF_SHUTR)) {
max = channel_recv_max(ic);
if (!max) {
}
end_recv:
- if (conn->flags & CO_FL_ERROR)
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
return;
if (cs->flags & CS_FL_EOS)
struct connection *conn = cs->conn;
struct stream_interface *si = cs->data;
- if (conn->flags & CO_FL_ERROR)
+ if (conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR)
return;
if (conn->flags & CO_FL_HANDSHAKE)