mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-04 20:46:11 +02:00
MINOR: proto_reverse_connect: handle early error before reversal
An error can occured on a reverse connection before accept is completed. In this case, no parent session can be notified. Instead, wake up the receiver task on conn_create_mux(). As a counterpart to this, receiver task is extended to match CO_FL_ERROR flag on pending connection. In this case, the onnection is freed. The task is then requeued with a 1 second delay to start a new reverse connection attempt.
This commit is contained in:
parent
47f502df5e
commit
b130f8dbc3
@ -91,8 +91,24 @@ int conn_create_mux(struct connection *conn)
|
||||
return 0;
|
||||
fail:
|
||||
/* let the upper layer know the connection failed */
|
||||
if (sc)
|
||||
if (sc) {
|
||||
sc->app_ops->wake(sc);
|
||||
}
|
||||
else if (conn_reverse_in_preconnect(conn)) {
|
||||
struct listener *l = conn_active_reverse_listener(conn);
|
||||
|
||||
/* If mux init failed, consider connection on error.
|
||||
* This is necessary to ensure connection is freed by
|
||||
* proto-reverse-connect receiver task.
|
||||
*/
|
||||
if (!conn->mux)
|
||||
conn->flags |= CO_FL_ERROR;
|
||||
|
||||
/* If connection is interrupted without CO_FL_ERROR, receiver task won't free it. */
|
||||
BUG_ON(!(conn->flags & CO_FL_ERROR));
|
||||
|
||||
task_wakeup(l->rx.reverse_connect.task, TASK_WOKEN_ANY);
|
||||
}
|
||||
return -1;
|
||||
} else
|
||||
return conn_complete_session(conn);
|
||||
@ -543,6 +559,8 @@ void conn_free(struct connection *conn)
|
||||
/* Receiver must reference a reverse connection as pending. */
|
||||
BUG_ON(!l->rx.reverse_connect.pend_conn);
|
||||
l->rx.reverse_connect.pend_conn = NULL;
|
||||
l->rx.reverse_connect.task->expire = MS_TO_TICKS(now_ms + 1000);
|
||||
task_queue(l->rx.reverse_connect.task);
|
||||
}
|
||||
|
||||
conn_force_unsubscribe(conn);
|
||||
|
||||
@ -107,11 +107,22 @@ struct task *rev_process(struct task *task, void *ctx, unsigned int state)
|
||||
struct connection *conn = l->rx.reverse_connect.pend_conn;
|
||||
|
||||
if (conn) {
|
||||
/* Spurrious receiver task wake up when pend_conn is not ready/on error. */
|
||||
BUG_ON(!(conn->flags & CO_FL_REVERSED));
|
||||
/* A connection is ready to be accepted. */
|
||||
listener_accept(l);
|
||||
l->rx.reverse_connect.task->expire = TICK_ETERNITY;
|
||||
if (conn->flags & CO_FL_ERROR) {
|
||||
conn_full_close(conn);
|
||||
conn_free(conn);
|
||||
l->rx.reverse_connect.pend_conn = NULL;
|
||||
|
||||
/* Retry on 1s on error. */
|
||||
l->rx.reverse_connect.task->expire = MS_TO_TICKS(now_ms + 1000);
|
||||
}
|
||||
else {
|
||||
/* Spurrious receiver task wake up when pend_conn is not ready/on error. */
|
||||
BUG_ON(!(conn->flags & CO_FL_REVERSED));
|
||||
|
||||
/* A connection is ready to be accepted. */
|
||||
listener_accept(l);
|
||||
l->rx.reverse_connect.task->expire = TICK_ETERNITY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* No pending reverse connection, prepare a new one. Store it in the
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user