MINOR: proto_reverse_connect: refactor preconnect failure
When a connection is freed during preconnect before reversal, the error must be notified to the listener to remove any connection reference and rearm a new preconnect attempt. Currently, this can occur through 2 code paths : * conn_free() called directly by H2 mux * error during conn_create_mux(). For this case, connection is flagged with CO_FL_ERROR and reverse_connect task is woken up. The process task handler is then responsible to call conn_free() for such connection. Duplicated steps where done both in conn_free() and process task handler. These are now removed. To facilitate code maintenance, dedicated operation have been centralized in a new function rev_notify_preconn_err() which is called by conn_free().
This commit is contained in:
parent
a37abee266
commit
1f43fb71be
|
@ -16,4 +16,6 @@ int rev_set_affinity(struct connection *conn, int new_tid);
|
|||
|
||||
int rev_accepting_conn(const struct receiver *rx);
|
||||
|
||||
void rev_notify_preconn_err(struct listener *l);
|
||||
|
||||
#endif /* _HAPROXY_PROTO_REVERSE_CONNECT_H */
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <haproxy/log-t.h>
|
||||
#include <haproxy/namespace.h>
|
||||
#include <haproxy/net_helper.h>
|
||||
#include <haproxy/proto_reverse_connect.h>
|
||||
#include <haproxy/proto_tcp.h>
|
||||
#include <haproxy/sample.h>
|
||||
#include <haproxy/sc_strm.h>
|
||||
|
@ -579,14 +580,7 @@ void conn_free(struct connection *conn)
|
|||
|
||||
if (conn_reverse_in_preconnect(conn)) {
|
||||
struct listener *l = conn_active_reverse_listener(conn);
|
||||
|
||||
/* For the moment reverse connection are bound only on first thread. */
|
||||
BUG_ON(tid != 0);
|
||||
/* 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);
|
||||
rev_notify_preconn_err(l);
|
||||
}
|
||||
|
||||
conn_force_unsubscribe(conn);
|
||||
|
|
|
@ -102,6 +102,26 @@ static struct connection *new_reverse_conn(struct listener *l, struct server *sr
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Report that a connection used for preconnect on listener <l> is freed before
|
||||
* reversal is completed. This is used to cleanup any reference to the
|
||||
* connection and rearm a new preconnect attempt.
|
||||
*/
|
||||
void rev_notify_preconn_err(struct listener *l)
|
||||
{
|
||||
/* For the moment reverse connection are bound only on first thread. */
|
||||
BUG_ON(tid != 0);
|
||||
|
||||
/* Receiver must reference a reverse connection as pending. */
|
||||
BUG_ON(!l->rx.reverse_connect.pend_conn);
|
||||
|
||||
/* Remove reference to the freed connection. */
|
||||
l->rx.reverse_connect.pend_conn = NULL;
|
||||
|
||||
/* Rearm a new preconnect attempt. */
|
||||
l->rx.reverse_connect.task->expire = MS_TO_TICKS(now_ms + 1000);
|
||||
task_queue(l->rx.reverse_connect.task);
|
||||
}
|
||||
|
||||
struct task *rev_process(struct task *task, void *ctx, unsigned int state)
|
||||
{
|
||||
struct listener *l = ctx;
|
||||
|
@ -111,10 +131,9 @@ struct task *rev_process(struct task *task, void *ctx, unsigned int state)
|
|||
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);
|
||||
/* conn_free() must report preconnect failure using rev_notify_preconn_err(). */
|
||||
BUG_ON(l->rx.reverse_connect.pend_conn);
|
||||
}
|
||||
else {
|
||||
/* Spurrious receiver task wake up when pend_conn is not ready/on error. */
|
||||
|
|
Loading…
Reference in New Issue