BUG/MEDIUM: conn-stream: Don't erase endpoint flags on reset

Only CS_EP_ERROR flag is now removed from the endpoint when a reset is
performed. When a new the endpoint is allocated, flags are preserved. It is
the caller responsibility to remove other flags, depending on its need.

Concretly, during a connection retry or a L7 retry, we must preserve
flags. In tcpcheck and the CLI, we reset flags.

This patch is 2.6-specific. No backport needed.
This commit is contained in:
Christopher Faulet 2022-04-28 18:25:24 +02:00
parent 04994de642
commit a6c4a48341
5 changed files with 17 additions and 3 deletions

View File

@ -1577,6 +1577,7 @@ static int connect_server(struct stream *s)
srv_conn = NULL;
if (cs_reset_endp(s->csb) < 0)
return SF_ERR_INTERNAL;
s->csb->endp->flags &= CS_EP_DETACHED;
}
}
else

View File

@ -1164,7 +1164,12 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
TRACE_DEVEL("closing current connection", CHK_EV_TASK_WAKE|CHK_EV_HCHK_RUN, check);
check->state &= ~CHK_ST_CLOSE_CONN;
conn = NULL;
cs_reset_endp(check->cs); /* error will be handled by tcpcheck_main() */
if (!cs_reset_endp(check->cs)) {
/* error will be handled by tcpcheck_main().
* On success, remove all flags except CS_EP_DETACHED
*/
check->cs->endp->flags &= CS_EP_DETACHED;
}
tcpcheck_main(check);
}
if (check->result == CHK_RES_UNKNOWN) {

View File

@ -2761,6 +2761,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
s->srv_error(s, s->csb);
return 1;
}
s->csb->endp->flags &= CS_EP_DETACHED;
}
sockaddr_free(&s->csb->dst);

View File

@ -392,7 +392,8 @@ static void cs_detach_endp(struct conn_stream **csp)
if (cs->endp) {
/* the cs is the only one one the endpoint */
cs_endpoint_init(cs->endp);
cs->endp->target = NULL;
cs->endp->ctx = NULL;
cs->endp->flags |= CS_EP_DETACHED;
}
@ -442,12 +443,17 @@ void cs_destroy(struct conn_stream *cs)
/* Resets the conn-stream endpoint. It happens when the app layer want to renew
* its endpoint. For a connection retry for instance. If a mux or an applet is
* attached, a new endpoint is created. Returns -1 on error and 0 on sucess.
*
* Only CS_EP_ERROR flag is removed on the endpoint. Orther flags are preserved.
* It is the caller responsibility to remove other flags if needed.
*/
int cs_reset_endp(struct conn_stream *cs)
{
struct cs_endpoint *new_endp;
BUG_ON(!cs->app);
cs->endp->flags &= ~CS_EP_ERROR;
if (!__cs_endp_target(cs)) {
/* endpoint not attached or attached to a mux with no
* target. Thus the endpoint will not be release but just
@ -465,6 +471,7 @@ int cs_reset_endp(struct conn_stream *cs)
cs->endp->flags |= CS_EP_ERROR;
return -1;
}
new_endp->flags = cs->endp->flags;
/* The app is still attached, the cs will not be released */
cs_detach_endp(&cs);

View File

@ -1246,7 +1246,6 @@ static __inline int do_l7_retry(struct stream *s, struct conn_stream *cs)
req->flags &= ~(CF_WRITE_ERROR | CF_WRITE_TIMEOUT | CF_SHUTW | CF_SHUTW_NOW);
res->flags &= ~(CF_READ_ERROR | CF_READ_TIMEOUT | CF_SHUTR | CF_EOI | CF_READ_NULL | CF_SHUTR_NOW);
res->analysers &= AN_RES_FLT_END;
cs->endp->flags &= ~CS_EP_RXBLK_SHUT;
s->conn_err_type = STRM_ET_NONE;
s->flags &= ~(SF_CONN_EXP | SF_ERR_MASK | SF_FINST_MASK);
s->conn_exp = TICK_ETERNITY;
@ -1261,6 +1260,7 @@ static __inline int do_l7_retry(struct stream *s, struct conn_stream *cs)
s->flags |= SF_ERR_INTERNAL;
return -1;
}
cs->endp->flags &= ~CS_EP_RXBLK_SHUT;
b_free(&req->buf);
/* Swap the L7 buffer with the channel buffer */