diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h index 2e79a129f..d759238b2 100644 --- a/include/haproxy/connection.h +++ b/include/haproxy/connection.h @@ -75,7 +75,7 @@ int conn_send_socks4_proxy_request(struct connection *conn); int conn_recv_socks4_proxy_response(struct connection *conn); /* If we delayed the mux creation because we were waiting for the handshake, do it now */ -int conn_create_mux(struct connection *conn); +int conn_create_mux(struct connection *conn, int *closed_connection); int conn_notify_mux(struct connection *conn, int old_flags, int forced_wake); int conn_upgrade_mux_fe(struct connection *conn, void *ctx, struct buffer *buf, struct ist mux_proto, int mode); diff --git a/src/backend.c b/src/backend.c index 451686b6a..5cfa26311 100644 --- a/src/backend.c +++ b/src/backend.c @@ -2217,8 +2217,11 @@ int connect_server(struct stream *s) /* catch all sync connect while the mux is not already installed */ if (!srv_conn->mux && !(srv_conn->flags & CO_FL_WAIT_XPRT)) { - if (conn_create_mux(srv_conn) < 0) { - conn_full_close(srv_conn); + int closed_connection; + + if (conn_create_mux(srv_conn, &closed_connection) < 0) { + if (closed_connection == 0) + conn_full_close(srv_conn); return SF_ERR_INTERNAL; } } diff --git a/src/connection.c b/src/connection.c index 09ec41bb6..e8509fc2d 100644 --- a/src/connection.c +++ b/src/connection.c @@ -84,8 +84,11 @@ void conn_delete_from_tree(struct connection *conn) eb64_delete(&conn->hash_node->node); } -int conn_create_mux(struct connection *conn) +int conn_create_mux(struct connection *conn, int *closed_connection) { + if (closed_connection) + *closed_connection = 0; + if (conn_is_back(conn)) { struct server *srv; struct stconn *sc = conn->ctx; @@ -138,8 +141,13 @@ fail: task_wakeup(l->rx.rhttp.task, TASK_WOKEN_RES); } return -1; - } else - return conn_complete_session(conn); + } else { + + int ret = conn_complete_session(conn); + if (ret == -1 && closed_connection) + *closed_connection = 1; + return ret; + } } @@ -157,7 +165,7 @@ int conn_notify_mux(struct connection *conn, int old_flags, int forced_wake) * done with the handshake, attempt to create one. */ if (unlikely(!conn->mux) && !(conn->flags & CO_FL_WAIT_XPRT)) { - ret = conn_create_mux(conn); + ret = conn_create_mux(conn, NULL); if (ret < 0) goto done; } diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 29c7df874..793862b94 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -5813,10 +5813,17 @@ struct task *ssl_sock_io_cb(struct task *t, void *context, unsigned int state) * woke a tasklet already. */ if (ctx->conn->xprt_ctx == ctx) { + int closed_connection = 0; + if (!ctx->conn->mux) - ret = conn_create_mux(ctx->conn); - if (ret >= 0 && !woke && ctx->conn->mux && ctx->conn->mux->wake) + ret = conn_create_mux(ctx->conn, &closed_connection); + if (ret >= 0 && !woke && ctx->conn->mux && ctx->conn->mux->wake) { ret = ctx->conn->mux->wake(ctx->conn); + if (ret < 0) + closed_connection = 1; + } + if (closed_connection) + t = NULL; goto leave; } } diff --git a/src/xprt_handshake.c b/src/xprt_handshake.c index 33f775087..4d6b4bb89 100644 --- a/src/xprt_handshake.c +++ b/src/xprt_handshake.c @@ -115,7 +115,7 @@ out: */ if (was_conn_ctx) { if (!ctx->conn->mux) - ret = conn_create_mux(ctx->conn); + ret = conn_create_mux(ctx->conn, NULL); if (ret >= 0 && !woke && ctx->conn->mux && ctx->conn->mux->wake) ret = ctx->conn->mux->wake(ctx->conn); }