]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: connection: inform si_alloc_conn() whether existing conn is OK or not
authorWilly Tarreau <w@1wt.eu>
Sun, 15 Dec 2013 12:31:35 +0000 (13:31 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 16 Dec 2013 01:23:53 +0000 (02:23 +0100)
When allocating a new connection, only the caller knows whether it's
acceptable to reuse the previous one or not. Let's pass this information
to si_alloc_conn() which will do the cleanup if the connection is not
acceptable.

include/proto/connection.h
include/proto/stream_interface.h
src/backend.c
src/proto_http.c

index be9d712f6b4c91e00ad54caac73138a9b0763c5d..e172cfe78ad4a1fe0d0eea2b15d5683a58806dce 100644 (file)
@@ -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)
 {
index 5408f1e05250003d0b775c81c6991885e730ef89..588b83e16cc833bcbeb7430cea08896c6639ebb2 100644 (file)
@@ -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 <reuse> 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);
        }
index c680777435e132a99125fe1e90f1e6f02eca82a9..657da9d256960791b4138fac5b347ee49ee33e5e 100644 (file)
@@ -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;
 
index a459c53bca9a8998e9ca12e1fb4f2b9795156852..a0717585a389afa78872b18872bdc883e6f515be 100644 (file)
@@ -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;