diff --git a/include/haproxy/stconn-t.h b/include/haproxy/stconn-t.h index 1bb137075..99b6e25bd 100644 --- a/include/haproxy/stconn-t.h +++ b/include/haproxy/stconn-t.h @@ -25,6 +25,7 @@ #include #include #include +#include /* Stream Endpoint Flags. * Please also update the se_show_flags() function below in case of changes. @@ -245,6 +246,7 @@ struct stconn; * is the last read activity * is the first send blocked * SE_FL_* + * cross reference with the opposite SC * * should be updated when a read activity is detected. It can be a * successful receive, when a shutr is reported or when receives are @@ -260,6 +262,7 @@ struct sedesc { unsigned int flags; unsigned int lra; unsigned int fsb; + struct xref xref; }; /* sc_app_ops describes the application layer's operations and notification diff --git a/src/stconn.c b/src/stconn.c index 39dcbb5f0..2339566d7 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -19,6 +19,7 @@ #include #include #include +#include DECLARE_POOL(pool_head_connstream, "stconn", sizeof(struct stconn)); DECLARE_POOL(pool_head_sedesc, "sedesc", sizeof(struct sedesc)); @@ -94,6 +95,7 @@ void sedesc_init(struct sedesc *sedesc) sedesc->sc = NULL; sedesc->lra = TICK_ETERNITY; sedesc->fsb = TICK_ETERNITY; + sedesc->xref.peer = NULL; se_fl_setall(sedesc, SE_FL_NONE); } @@ -271,6 +273,7 @@ int sc_attach_mux(struct stconn *sc, void *sd, void *ctx) } sc->app_ops = &sc_app_conn_ops; + xref_create(&sc->sedesc->xref, &sc_opposite(sc)->sedesc->xref); } else if (sc_check(sc)) { if (!sc->wait_event.tasklet) { @@ -304,8 +307,10 @@ static void sc_attach_applet(struct stconn *sc, void *sd) sc->sedesc->se = sd; sc_ep_set(sc, SE_FL_T_APPLET); sc_ep_clr(sc, SE_FL_DETACHED); - if (sc_strm(sc)) + if (sc_strm(sc)) { sc->app_ops = &sc_app_applet_ops; + xref_create(&sc->sedesc->xref, &sc_opposite(sc)->sedesc->xref); + } } /* Attaches a stconn to a app layer and sets the relevant @@ -350,6 +355,15 @@ static void sc_detach_endp(struct stconn **scp) if (!sc) return; + if (sc->sedesc) { + struct xref *peer; + + /* Remove my link in the original objects. */ + peer = xref_get_peer_and_lock(&sc->sedesc->xref); + if (peer) + xref_disconnect(&sc->sedesc->xref, peer); + } + if (sc_ep_test(sc, SE_FL_T_MUX)) { struct connection *conn = __sc_conn(sc); struct sedesc *sedesc = sc->sedesc;