BUG/MEDIUM: connections: Report connection closing in conn_create_mux()
Add an extra parametre to conn_create_mux(), "closed_connection". If a pointer is provided, then let it know if the connection was closed. Callers have no way to determine that otherwise, and we need to know that, at least in ssl_sock_io_cb(), as if the connection was closed we need to return NULL, as the tasklet was free'd, otherwise that can lead to memory corruption and crashes. This should be backported if 9240cd4a2771245fae4d0d69ef025104b14bfc23 is backported too.
This commit is contained in:
parent
b81c9390f4
commit
b138eab302
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user