From: Amaury Denoyelle Date: Tue, 26 Jan 2021 16:35:46 +0000 (+0100) Subject: BUG/MEDIUM: backend: never reuse a connection for tcp mode X-Git-Tag: v2.4-dev7~120 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=08d87b3f49867440f66aee09173c84bf58cbc859;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: backend: never reuse a connection for tcp mode The reuse of idle connections should only happen for a proxy with the http mode. In case of a backend with the tcp mode, the reuse selection and insertion in session list are skipped. This behavior is present since commit : MEDIUM: connection: Add private connections synchronously in session server list It could also be further exagerated by : MEDIUM: backend: add reused conn to sess if mux marked as HOL blocking It can be backported up to 2.3. --- diff --git a/src/backend.c b/src/backend.c index 0d0447d7bc..f3f42230bb 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1248,13 +1248,16 @@ int connect_server(struct stream *s) */ si_release_endpoint(&s->si[1]); + srv = objt_server(s->target); + + if (s->be->mode != PR_MODE_HTTP) + goto skip_reuse; + /* first, search for a matching connection in the session's idle conns */ srv_conn = session_get_conn(s->sess, s->target); if (srv_conn) reuse = 1; - srv = objt_server(s->target); - if (srv && !reuse && reuse_mode != PR_O_REUSE_NEVR) { /* Below we pick connections from the safe, idle or * available (which are safe too) lists based @@ -1391,6 +1394,7 @@ int connect_server(struct stream *s) else srv_conn = NULL; +skip_reuse: /* no reuse or failed to reuse the connection above, pick a new one */ if (!srv_conn) { srv_conn = conn_new(s->target); @@ -1541,21 +1545,26 @@ int connect_server(struct stream *s) conn_full_close(srv_conn); return SF_ERR_INTERNAL; } - /* If we're doing http-reuse always, and the connection is not - * private with available streams (an http2 connection), add it - * to the available list, so that others can use it right - * away. If the connection is private or we're doing http-reuse - * safe and the mux protocol supports multiplexing, add it in - * the session server list. - */ - if (srv && reuse_mode == PR_O_REUSE_ALWS && - !(srv_conn->flags & CO_FL_PRIVATE) && srv_conn->mux->avail_streams(srv_conn) > 0) - LIST_ADDQ(&srv->available_conns[tid], mt_list_to_list(&srv_conn->list)); - else if (srv_conn->flags & CO_FL_PRIVATE || - (reuse_mode == PR_O_REUSE_SAFE && - srv_conn->mux->flags & MX_FL_HOL_RISK)) { - /* If it fail now, the same will be done in mux->detach() callback */ - session_add_conn(s->sess, srv_conn, srv_conn->target); + if (s->be->mode != PR_MODE_HTTP) { + /* If we're doing http-reuse always, and the connection + * is not private with available streams (an http2 + * connection), add it to the available list, so that + * others can use it right away. If the connection is + * private or we're doing http-reuse safe and the mux + * protocol supports multiplexing, add it in the + * session server list. + */ + if (srv && reuse_mode == PR_O_REUSE_ALWS && + !(srv_conn->flags & CO_FL_PRIVATE) && + srv_conn->mux->avail_streams(srv_conn) > 0) { + LIST_ADDQ(&srv->available_conns[tid], mt_list_to_list(&srv_conn->list)); + } + else if (srv_conn->flags & CO_FL_PRIVATE || + (reuse_mode == PR_O_REUSE_SAFE && + srv_conn->mux->flags & MX_FL_HOL_RISK)) { + /* If it fail now, the same will be done in mux->detach() callback */ + session_add_conn(s->sess, srv_conn, srv_conn->target); + } } }