From: Christopher Faulet Date: Tue, 16 Apr 2024 16:36:40 +0000 (+0200) Subject: MEDIUM: stconn: Use one function to shut connection and applet endpoints X-Git-Tag: v3.0-dev8~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e38ac72cedbf6f7ddaa89802cf4d4326a0e3860;p=thirdparty%2Fhaproxy.git MEDIUM: stconn: Use one function to shut connection and applet endpoints se_shutdown() function is now used to perform a shutdown on a connection endpoint and an applet endpoint. The same function is used for both. sc_conn_shut() function was removed and appctx_shut() function was updated to only deal with the applet stuff. --- diff --git a/include/haproxy/applet.h b/include/haproxy/applet.h index 7c8513380c..7f71083ee1 100644 --- a/include/haproxy/applet.h +++ b/include/haproxy/applet.h @@ -42,7 +42,7 @@ struct task *task_process_applet(struct task *t, void *context, unsigned int sta int appctx_buf_available(void *arg); void *applet_reserve_svcctx(struct appctx *appctx, size_t size); void applet_reset_svcctx(struct appctx *appctx); -void appctx_shut(struct appctx *appctx, enum se_shut_mode mode); +void appctx_shut(struct appctx *appctx); struct appctx *appctx_new_on(struct applet *applet, struct sedesc *sedesc, int thr); int appctx_finalize_startup(struct appctx *appctx, struct proxy *px, struct buffer *input); diff --git a/include/haproxy/stconn.h b/include/haproxy/stconn.h index e2409011c6..14ccd75a2d 100644 --- a/include/haproxy/stconn.h +++ b/include/haproxy/stconn.h @@ -39,6 +39,8 @@ struct check; struct sedesc *sedesc_new(); void sedesc_free(struct sedesc *sedesc); +void se_shutdown(struct sedesc *sedesc, enum se_shut_mode mode); + struct stconn *sc_new_from_endp(struct sedesc *sedesc, struct session *sess, struct buffer *input); struct stconn *sc_new_from_strm(struct stream *strm, unsigned int flags); struct stconn *sc_new_from_check(struct check *check, unsigned int flags); @@ -318,27 +320,6 @@ static inline const char *sc_get_data_name(const struct stconn *sc) return sc->app_ops->name; } -static inline void sc_conn_shut(struct stconn *sc, enum se_shut_mode mode) -{ - const struct mux_ops *mux; - - BUG_ON(!sc_conn(sc)); - - mux = sc_mux_ops(sc); - - if ((mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) && !sc_ep_test(sc, SE_FL_SHW)) { - if (mux && mux->shutw) - mux->shutw(sc, mode); - sc_ep_set(sc, (mode & SE_SHW_NORMAL) ? SE_FL_SHWN : SE_FL_SHWS); - } - - if ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !sc_ep_test(sc, SE_FL_SHR)) { - if (mux && mux->shutr) - mux->shutr(sc, mode); - sc_ep_set(sc, (mode & SE_SHR_DRAIN) ? SE_FL_SHRD : SE_FL_SHRR); - } -} - /* Returns non-zero if the stream connector's Rx path is blocked because of * lack of room in the input buffer. This usually happens after applets failed * to deliver data into the channel's buffer and reported it via sc_need_room(). diff --git a/src/applet.c b/src/applet.c index a6d677cec2..b21979a525 100644 --- a/src/applet.c +++ b/src/applet.c @@ -394,26 +394,19 @@ void applet_reset_svcctx(struct appctx *appctx) /* call the applet's release() function if any, and marks the sedesc as shut * once both read and write side are shut. Needs to be called upon close(). */ -void appctx_shut(struct appctx *appctx, enum se_shut_mode mode) +void appctx_shut(struct appctx *appctx) { if (applet_fl_test(appctx, APPCTX_FL_SHUTDOWN)) return; TRACE_ENTER(APPLET_EV_RELEASE, appctx); - if ((mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) && !se_fl_test(appctx->sedesc, SE_FL_SHW)) - se_fl_set(appctx->sedesc, SE_FL_SHWN); - if ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !se_fl_test(appctx->sedesc, SE_FL_SHR)) - se_fl_set(appctx->sedesc, SE_FL_SHRR); + if (appctx->applet->release) + appctx->applet->release(appctx); + applet_fl_set(appctx, APPCTX_FL_SHUTDOWN); - if (se_fl_test(appctx->sedesc, SE_FL_SHR) && se_fl_test(appctx->sedesc, SE_FL_SHW)) { - if (appctx->applet->release) - appctx->applet->release(appctx); - applet_fl_set(appctx, APPCTX_FL_SHUTDOWN); - - if (LIST_INLIST(&appctx->buffer_wait.list)) - LIST_DEL_INIT(&appctx->buffer_wait.list); - } + if (LIST_INLIST(&appctx->buffer_wait.list)) + LIST_DEL_INIT(&appctx->buffer_wait.list); TRACE_LEAVE(APPLET_EV_RELEASE, appctx); } diff --git a/src/check.c b/src/check.c index 6a37ad8871..ff6977cf09 100644 --- a/src/check.c +++ b/src/check.c @@ -1382,7 +1382,7 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state) * as a failed response coupled with "observe layer7" caused the * server state to be suddenly changed. */ - sc_conn_shut(sc, SE_SHR_DRAIN|SE_SHW_SILENT); + se_shutdown(sc->sedesc, SE_SHR_DRAIN|SE_SHW_SILENT); } if (sc) { diff --git a/src/stconn.c b/src/stconn.c index 669601c472..ca878436ae 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -131,6 +131,40 @@ void sedesc_free(struct sedesc *sedesc) } } +/* Performs a shutdown on the endpoint. This function deals with connection and + * applet endpoints. It is responsible to set SE flags corresponding to the + * given shut modes and to call right shutdown functions of the endpoint. It is + * called from the .abort and .shut app_ops callback functions at the SC level. + */ +void se_shutdown(struct sedesc *sedesc, enum se_shut_mode mode) +{ + if (se_fl_test(sedesc, SE_FL_T_MUX)) { + const struct mux_ops *mux = (sedesc->conn ? sedesc->conn->mux : NULL); + + if ((mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) && !se_fl_test(sedesc, SE_FL_SHW)) { + if (mux && mux->shutw) + mux->shutw(sedesc->sc, mode); + se_fl_set(sedesc, (mode & SE_SHW_NORMAL) ? SE_FL_SHWN : SE_FL_SHWS); + } + + if ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !se_fl_test(sedesc, SE_FL_SHR)) { + if (mux && mux->shutr) + mux->shutr(sedesc->sc, mode); + se_fl_set(sedesc, (mode & SE_SHR_DRAIN) ? SE_FL_SHRD : SE_FL_SHRR); + } + } + else if (se_fl_test(sedesc, SE_FL_T_APPLET)) { + if ((mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) && !se_fl_test(sedesc, SE_FL_SHW)) + se_fl_set(sedesc, SE_FL_SHWN); + + if ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !se_fl_test(sedesc, SE_FL_SHR)) + se_fl_set(sedesc, SE_FL_SHRR); + + if (se_fl_test(sedesc, SE_FL_SHR) && se_fl_test(sedesc, SE_FL_SHW)) + appctx_shut(sedesc->se); + } +} + /* Tries to allocate a new stconn and initialize its main fields. On * failure, nothing is allocated and NULL is returned. It is an internal * function. The caller must, at least, set the SE_FL_ORPHAN or SE_FL_DETACHED @@ -405,7 +439,7 @@ static void sc_detach_endp(struct stconn **scp) sc_ep_set(sc, SE_FL_ORPHAN); sc->sedesc->sc = NULL; sc->sedesc = NULL; - appctx_shut(appctx, SE_SHR_RESET|SE_SHW_NORMAL); + se_shutdown(appctx->sedesc, SE_SHR_RESET|SE_SHW_NORMAL); appctx_free(appctx); } @@ -700,7 +734,7 @@ static void sc_app_abort_conn(struct stconn *sc) return; if (sc->flags & SC_FL_SHUT_DONE) { - sc_conn_shut(sc, SE_SHR_RESET|SE_SHW_SILENT); + se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_SILENT); sc->state = SC_ST_DIS; if (sc->flags & SC_FL_ISBACK) __sc_strm(sc)->conn_exp = TICK_ETERNITY; @@ -742,11 +776,11 @@ static void sc_app_shut_conn(struct stconn *sc) * no risk so we close both sides immediately. */ if (!(sc->flags & (SC_FL_NOLINGER|SC_FL_EOS|SC_FL_ABRT_DONE)) && !(ic->flags & CF_DONT_READ)) { - sc_conn_shut(sc, SE_SHW_NORMAL); + se_shutdown(sc->sedesc, SE_SHW_NORMAL); return; } - sc_conn_shut(sc, SE_SHR_RESET|((sc->flags & SC_FL_NOLINGER) ? SE_SHW_SILENT : SE_SHW_NORMAL)); + se_shutdown(sc->sedesc, SE_SHR_RESET|((sc->flags & SC_FL_NOLINGER) ? SE_SHW_SILENT : SE_SHW_NORMAL)); sc->state = SC_ST_DIS; break; @@ -754,7 +788,7 @@ static void sc_app_shut_conn(struct stconn *sc) /* we may have to close a pending connection, and mark the * response buffer as abort */ - sc_conn_shut(sc, SE_SHR_RESET|SE_SHW_SILENT); + se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_SILENT); sc->state = SC_ST_DIS; break; case SC_ST_CER: @@ -884,7 +918,7 @@ static void sc_app_abort_applet(struct stconn *sc) return; if (sc->flags & SC_FL_SHUT_DONE) { - appctx_shut(__sc_appctx(sc), SE_SHR_RESET|SE_SHW_NORMAL); + se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_NORMAL); sc->state = SC_ST_DIS; if (sc->flags & SC_FL_ISBACK) __sc_strm(sc)->conn_exp = TICK_ETERNITY; @@ -929,11 +963,11 @@ static void sc_app_shut_applet(struct stconn *sc) */ if (!(sc->flags & (SC_FL_ERROR|SC_FL_NOLINGER|SC_FL_EOS|SC_FL_ABRT_DONE)) && !(ic->flags & CF_DONT_READ)) { - appctx_shut(__sc_appctx(sc), SE_SHW_NORMAL); + se_shutdown(sc->sedesc, SE_SHW_NORMAL); return; } - appctx_shut(__sc_appctx(sc), SE_SHR_RESET|SE_SHW_NORMAL); + se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_NORMAL); sc->state = SC_ST_DIS; break; @@ -942,7 +976,7 @@ static void sc_app_shut_applet(struct stconn *sc) case SC_ST_QUE: case SC_ST_TAR: /* Note that none of these states may happen with applets */ - appctx_shut(__sc_appctx(sc), SE_SHR_RESET|SE_SHW_NORMAL); + se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_NORMAL); sc->state = SC_ST_DIS; break; default: @@ -1202,7 +1236,7 @@ static void sc_conn_eos(struct stconn *sc) do_close: /* OK we completely close the socket here just as if we went through sc_shut[rw]() */ - sc_conn_shut(sc, SE_SHR_RESET|SE_SHW_SILENT); + se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_SILENT); sc->flags &= ~SC_FL_SHUT_WANTED; sc->flags |= SC_FL_SHUT_DONE; @@ -1866,7 +1900,7 @@ static void sc_applet_eos(struct stconn *sc) return; if (sc->flags & SC_FL_SHUT_DONE) { - appctx_shut(__sc_appctx(sc), SE_SHR_RESET|SE_SHW_NORMAL); + se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_NORMAL); sc->state = SC_ST_DIS; if (sc->flags & SC_FL_ISBACK) __sc_strm(sc)->conn_exp = TICK_ETERNITY;