diff --git a/include/proto/connection.h b/include/proto/connection.h index be9d712f6..e172cfe78 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -126,7 +126,8 @@ static inline void conn_full_close(struct connection *conn) } /* Force to close the connection whatever the tracking state. This is mainly - * used on the error path where the tracking does not make sense. + * used on the error path where the tracking does not make sense, or to kill + * an idle connection we want to abort immediately. */ static inline void conn_force_close(struct connection *conn) { diff --git a/include/proto/stream_interface.h b/include/proto/stream_interface.h index 5408f1e05..588b83e16 100644 --- a/include/proto/stream_interface.h +++ b/include/proto/stream_interface.h @@ -212,11 +212,15 @@ static inline void si_applet_release(struct stream_interface *si) applet->release(si); } +/* Try to allocate a new connection and assign it to the interface. If + * a connection was previously allocated and the flag is set, + * it is returned unmodified. Otherwise it is reset. + */ /* Returns the stream interface's existing connection if one such already * exists, or tries to allocate and initialize a new one which is then * assigned to the stream interface. */ -static inline struct connection *si_alloc_conn(struct stream_interface *si) +static inline struct connection *si_alloc_conn(struct stream_interface *si, int reuse) { struct connection *conn; @@ -225,8 +229,13 @@ static inline struct connection *si_alloc_conn(struct stream_interface *si) */ if (si->end) { conn = objt_conn(si->end); - if (conn) + if (conn) { + if (!reuse) { + conn_force_close(conn); + conn_init(conn); + } return conn; + } /* it was an applet then */ si_release_endpoint(si); } diff --git a/src/backend.c b/src/backend.c index c68077743..657da9d25 100644 --- a/src/backend.c +++ b/src/backend.c @@ -982,7 +982,7 @@ static void assign_tproxy_address(struct session *s) int connect_server(struct session *s) { struct connection *cli_conn; - struct connection *srv_conn = si_alloc_conn(s->req->cons); + struct connection *srv_conn = si_alloc_conn(s->req->cons, 0); struct server *srv; int err; diff --git a/src/proto_http.c b/src/proto_http.c index a459c53bc..a0717585a 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -3742,7 +3742,8 @@ int http_process_request(struct session *s, struct channel *req, int an_bit) if ((s->be->options & PR_O_HTTP_PROXY) && !(s->flags & SN_ADDR_SET)) { struct connection *conn; - if (unlikely((conn = si_alloc_conn(req->cons)) == NULL)) { + /* Note that for now we don't reuse existing proxy connections */ + if (unlikely((conn = si_alloc_conn(req->cons, 0)) == NULL)) { txn->req.msg_state = HTTP_MSG_ERROR; txn->status = 500; req->analysers = 0;