/*
 * stream connector management functions
 *
 * Copyright 2021 Christopher Faulet <cfaulet@haproxy.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#include <haproxy/api.h>
#include <haproxy/applet.h>
#include <haproxy/connection.h>
#include <haproxy/check.h>
#include <haproxy/http_ana.h>
#include <haproxy/pipe.h>
#include <haproxy/pool.h>
#include <haproxy/sc_strm.h>
#include <haproxy/stconn.h>

DECLARE_POOL(pool_head_connstream, "stconn", sizeof(struct stconn));
DECLARE_POOL(pool_head_sedesc, "sedesc", sizeof(struct sedesc));

/* functions used by default on a detached stream connector */
static void sc_app_shutr(struct stconn *sc);
static void sc_app_shutw(struct stconn *sc);
static void sc_app_chk_rcv(struct stconn *sc);
static void sc_app_chk_snd(struct stconn *sc);

/* functions used on a mux-based stream connector */
static void sc_app_shutr_conn(struct stconn *sc);
static void sc_app_shutw_conn(struct stconn *sc);
static void sc_app_chk_rcv_conn(struct stconn *sc);
static void sc_app_chk_snd_conn(struct stconn *sc);

/* functions used on an applet-based stream connector */
static void sc_app_shutr_applet(struct stconn *sc);
static void sc_app_shutw_applet(struct stconn *sc);
static void sc_app_chk_rcv_applet(struct stconn *sc);
static void sc_app_chk_snd_applet(struct stconn *sc);

static int sc_conn_process(struct stconn *sc);
static int sc_conn_recv(struct stconn *sc);
static int sc_conn_send(struct stconn *sc);
static int sc_applet_process(struct stconn *sc);

/* stream connector operations for connections */
struct sc_app_ops sc_app_conn_ops = {
	.chk_rcv = sc_app_chk_rcv_conn,
	.chk_snd = sc_app_chk_snd_conn,
	.shutr   = sc_app_shutr_conn,
	.shutw   = sc_app_shutw_conn,
	.wake    = sc_conn_process,
	.name    = "STRM",
};

/* stream connector operations for embedded tasks */
struct sc_app_ops sc_app_embedded_ops = {
	.chk_rcv = sc_app_chk_rcv,
	.chk_snd = sc_app_chk_snd,
	.shutr   = sc_app_shutr,
	.shutw   = sc_app_shutw,
	.wake    = NULL,   /* may never be used */
	.name    = "NONE", /* may never be used */
};

/* stream connector operations for applets */
struct sc_app_ops sc_app_applet_ops = {
	.chk_rcv = sc_app_chk_rcv_applet,
	.chk_snd = sc_app_chk_snd_applet,
	.shutr   = sc_app_shutr_applet,
	.shutw   = sc_app_shutw_applet,
	.wake    = sc_applet_process,
	.name    = "STRM",
};

/* stream connector for health checks on connections */
struct sc_app_ops sc_app_check_ops = {
	.chk_rcv = NULL,
	.chk_snd = NULL,
	.shutr   = NULL,
	.shutw   = NULL,
	.wake    = wake_srv_chk,
	.name    = "CHCK",
};

/* Initializes an endpoint */
void sedesc_init(struct sedesc *sedesc)
{
	sedesc->se = NULL;
	sedesc->conn = NULL;
	sedesc->sc = NULL;
	se_fl_setall(sedesc, SE_FL_NONE);
}

/* Tries to alloc an endpoint and initialize it. Returns NULL on failure. */
struct sedesc *sedesc_new()
{
	struct sedesc *sedesc;

	sedesc = pool_alloc(pool_head_sedesc);
	if (unlikely(!sedesc))
		return NULL;

	sedesc_init(sedesc);
	return sedesc;
}

/* Releases an endpoint. It is the caller responsibility to be sure it is safe
 * and it is not shared with another entity
 */
void sedesc_free(struct sedesc *sedesc)
{
	pool_free(pool_head_sedesc, sedesc);
}

/* 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
 * flag.
 */
static struct stconn *sc_new(struct sedesc *sedesc)
{
	struct stconn *sc;

	sc = pool_alloc(pool_head_connstream);

	if (unlikely(!sc))
		goto alloc_error;

	sc->obj_type = OBJ_TYPE_SC;
	sc->flags = SC_FL_NONE;
	sc->state = SC_ST_INI;
	sc->hcto = TICK_ETERNITY;
	sc->app = NULL;
	sc->app_ops = NULL;
	sc->src = NULL;
	sc->dst = NULL;
	sc->wait_event.tasklet = NULL;
	sc->wait_event.events = 0;

	/* If there is no endpoint, allocate a new one now */
	if (!sedesc) {
		sedesc = sedesc_new();
		if (unlikely(!sedesc))
			goto alloc_error;
	}
	sc->sedesc = sedesc;
	sedesc->sc = sc;

	return sc;

  alloc_error:
	pool_free(pool_head_connstream, sc);
	return NULL;
}

/* Creates a new stream connector and its associated stream from a mux. <sd> must
 * be defined. It returns NULL on error. On success, the new stream connector is
 * returned. In this case, SE_FL_ORPHAN flag is removed.
 */
struct stconn *sc_new_from_endp(struct sedesc *sd, struct session *sess, struct buffer *input)
{
	struct stconn *sc;

	sc = sc_new(sd);
	if (unlikely(!sc))
		return NULL;
	if (unlikely(!stream_new(sess, sc, input))) {
		pool_free(pool_head_connstream, sc);
		sd->sc = NULL;
		se_fl_set(sd, SE_FL_ORPHAN);
		return NULL;
	}
	se_fl_clr(sd, SE_FL_ORPHAN);
	return sc;
}

/* Creates a new stream connector from an stream. There is no endpoint here, thus it
 * will be created by sc_new(). So the SE_FL_DETACHED flag is set. It returns
 * NULL on error. On success, the new stream connector is returned.
 */
struct stconn *sc_new_from_strm(struct stream *strm, unsigned int flags)
{
	struct stconn *sc;

	sc = sc_new(NULL);
	if (unlikely(!sc))
		return NULL;
	sc->flags |= flags;
	sc_ep_set(sc, SE_FL_DETACHED);
	sc->app = &strm->obj_type;
	sc->app_ops = &sc_app_embedded_ops;
	return sc;
}

/* Creates a new stream connector from an health-check. There is no endpoint here,
 * thus it will be created by sc_new(). So the SE_FL_DETACHED flag is set. It
 * returns NULL on error. On success, the new stream connector is returned.
 */
struct stconn *sc_new_from_check(struct check *check, unsigned int flags)
{
	struct stconn *sc;

	sc = sc_new(NULL);
	if (unlikely(!sc))
		return NULL;
	sc->flags |= flags;
	sc_ep_set(sc, SE_FL_DETACHED);
	sc->app = &check->obj_type;
	sc->app_ops = &sc_app_check_ops;
	return sc;
}

/* Releases a stconn previously allocated by sc_new(), as well as its
 * endpoint, if it exists. This function is called internally or on error path.
 */
void sc_free(struct stconn *sc)
{
	sockaddr_free(&sc->src);
	sockaddr_free(&sc->dst);
	if (sc->sedesc) {
		BUG_ON(!sc_ep_test(sc, SE_FL_DETACHED));
		sedesc_free(sc->sedesc);
	}
	if (sc->wait_event.tasklet)
		tasklet_free(sc->wait_event.tasklet);
	pool_free(pool_head_connstream, sc);
}

/* Conditionally removes a stream connector if it is detached and if there is no app
 * layer defined. Except on error path, this one must be used. if release, the
 * pointer on the SC is set to NULL.
 */
static void sc_free_cond(struct stconn **scp)
{
	struct stconn *sc = *scp;

	if (!sc->app && (!sc->sedesc || sc_ep_test(sc, SE_FL_DETACHED))) {
		sc_free(sc);
		*scp = NULL;
	}
}


/* Attaches a stconn to a mux endpoint and sets the endpoint ctx. Returns
 * -1 on error and 0 on success. SE_FL_DETACHED flag is removed. This function is
 * called from a mux when it is attached to a stream or a health-check.
 */
int sc_attach_mux(struct stconn *sc, void *sd, void *ctx)
{
	struct connection *conn = ctx;
	struct sedesc *sedesc = sc->sedesc;

	sedesc->se = sd;
	sedesc->conn = ctx;
	se_fl_set(sedesc, SE_FL_T_MUX);
	se_fl_clr(sedesc, SE_FL_DETACHED);
	if (!conn->ctx)
		conn->ctx = sc;
	if (sc_strm(sc)) {
		if (!sc->wait_event.tasklet) {
			sc->wait_event.tasklet = tasklet_new();
			if (!sc->wait_event.tasklet)
				return -1;
			sc->wait_event.tasklet->process = sc_conn_io_cb;
			sc->wait_event.tasklet->context = sc;
			sc->wait_event.events = 0;
		}

		sc->app_ops = &sc_app_conn_ops;
	}
	else if (sc_check(sc)) {
		if (!sc->wait_event.tasklet) {
			sc->wait_event.tasklet = tasklet_new();
			if (!sc->wait_event.tasklet)
				return -1;
			sc->wait_event.tasklet->process = srv_chk_io_cb;
			sc->wait_event.tasklet->context = sc;
			sc->wait_event.events = 0;
		}

		sc->app_ops = &sc_app_check_ops;
	}
	return 0;
}

/* Attaches a stconn to an applet endpoint and sets the endpoint
 * ctx. Returns -1 on error and 0 on success. SE_FL_DETACHED flag is
 * removed. This function is called by a stream when a backend applet is
 * registered.
 */
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))
		sc->app_ops = &sc_app_applet_ops;
}

/* Attaches a stconn to a app layer and sets the relevant
 * callbacks. Returns -1 on error and 0 on success. SE_FL_ORPHAN flag is
 * removed. This function is called by a stream when it is created to attach it
 * on the stream connector on the client side.
 */
int sc_attach_strm(struct stconn *sc, struct stream *strm)
{
	sc->app = &strm->obj_type;
	sc_ep_clr(sc, SE_FL_ORPHAN);
	if (sc_ep_test(sc, SE_FL_T_MUX)) {
		sc->wait_event.tasklet = tasklet_new();
		if (!sc->wait_event.tasklet)
			return -1;
		sc->wait_event.tasklet->process = sc_conn_io_cb;
		sc->wait_event.tasklet->context = sc;
		sc->wait_event.events = 0;

		sc->app_ops = &sc_app_conn_ops;
	}
	else if (sc_ep_test(sc, SE_FL_T_APPLET)) {
		sc->app_ops = &sc_app_applet_ops;
	}
	else {
		sc->app_ops = &sc_app_embedded_ops;
	}
	return 0;
}

/* Detaches the stconn from the endpoint, if any. For a connecrion, if a
 * mux owns the connection ->detach() callback is called. Otherwise, it means
 * the stream connector owns the connection. In this case the connection is closed
 * and released. For an applet, the appctx is released. If still allocated, the
 * endpoint is reset and flag as detached. If the app layer is also detached,
 * the stream connector is released.
 */
static void sc_detach_endp(struct stconn **scp)
{
	struct stconn *sc = *scp;

	if (!sc)
		return;

	if (sc_ep_test(sc, SE_FL_T_MUX)) {
		struct connection *conn = __sc_conn(sc);
		struct sedesc *sedesc = sc->sedesc;

		if (conn->mux) {
			if (sc->wait_event.events != 0)
				conn->mux->unsubscribe(sc, sc->wait_event.events, &sc->wait_event);
			se_fl_set(sedesc, SE_FL_ORPHAN);
			sedesc->sc = NULL;
			sc->sedesc = NULL;
			conn->mux->detach(sedesc);
		}
		else {
			/* It's too early to have a mux, let's just destroy
			 * the connection
			 */
			conn_stop_tracking(conn);
			conn_full_close(conn);
			if (conn->destroy_cb)
				conn->destroy_cb(conn);
			conn_free(conn);
		}
	}
	else if (sc_ep_test(sc, SE_FL_T_APPLET)) {
		struct appctx *appctx = __sc_appctx(sc);

		sc_ep_set(sc, SE_FL_ORPHAN);
		sc->sedesc->sc = NULL;
		sc->sedesc = NULL;
		appctx_shut(appctx);
		appctx_free(appctx);
	}

	if (sc->sedesc) {
		/* the SD wasn't used and can be recycled */
		sc->sedesc->se     = NULL;
		sc->sedesc->conn   = NULL;
		sc->sedesc->flags  = 0;
		sc_ep_set(sc, SE_FL_DETACHED);
	}

	/* FIXME: Rest SC for now but must be reviewed. SC flags are only
	 *        connection related for now but this will evolved
	 */
	sc->flags &= SC_FL_ISBACK;
	if (sc_strm(sc))
		sc->app_ops = &sc_app_embedded_ops;
	else
		sc->app_ops = NULL;
	sc_free_cond(scp);
}

/* Detaches the stconn from the app layer. If there is no endpoint attached
 * to the stconn
 */
static void sc_detach_app(struct stconn **scp)
{
	struct stconn *sc = *scp;

	if (!sc)
		return;

	sc->app = NULL;
	sc->app_ops = NULL;
	sockaddr_free(&sc->src);
	sockaddr_free(&sc->dst);

	if (sc->wait_event.tasklet)
		tasklet_free(sc->wait_event.tasklet);
	sc->wait_event.tasklet = NULL;
	sc->wait_event.events = 0;
	sc_free_cond(scp);
}

/* Destroy the stconn. It is detached from its endpoint and its
 * application. After this call, the stconn must be considered as released.
 */
void sc_destroy(struct stconn *sc)
{
	sc_detach_endp(&sc);
	sc_detach_app(&sc);
	BUG_ON_HOT(sc);
}

/* Resets the stream connector endpoint. It happens when the app layer want to renew
 * its endpoint. For a connection retry for instance. If a mux or an applet is
 * attached, a new endpoint is created. Returns -1 on error and 0 on success.
 *
 * Only SE_FL_ERROR flag is removed on the endpoint. Orther flags are preserved.
 * It is the caller responsibility to remove other flags if needed.
 */
int sc_reset_endp(struct stconn *sc)
{
	struct sedesc *new_sd;

	BUG_ON(!sc->app);

	sc_ep_clr(sc, SE_FL_ERROR);
	if (!__sc_endp(sc)) {
		/* endpoint not attached or attached to a mux with no
		 * target. Thus the endpoint will not be release but just
		 * reset. The app is still attached, the sc will not be
		 * released.
		 */
		sc_detach_endp(&sc);
		return 0;
	}

	/* allocate the new endpoint first to be able to set error if it
	 * fails */
	new_sd = sedesc_new();
	if (!unlikely(new_sd)) {
		sc_ep_set(sc, SE_FL_ERROR);
		return -1;
	}

	/* The app is still attached, the sc will not be released */
	sc_detach_endp(&sc);
	BUG_ON(!sc);
	BUG_ON(sc->sedesc);
	sc->sedesc = new_sd;
	sc->sedesc->sc = sc;
	sc_ep_set(sc, SE_FL_DETACHED);
	return 0;
}


/* Create an applet to handle a stream connector as a new appctx. The SC will
 * wake it up every time it is solicited. The appctx must be deleted by the task
 * handler using sc_detach_endp(), possibly from within the function itself.
 * It also pre-initializes the applet's context and returns it (or NULL in case
 * it could not be allocated).
 */
struct appctx *sc_applet_create(struct stconn *sc, struct applet *app)
{
	struct appctx *appctx;

	DPRINTF(stderr, "registering handler %p for sc %p (was %p)\n", app, sc, sc_strm_task(sc));

	appctx = appctx_new_here(app, sc->sedesc);
	if (!appctx)
		return NULL;
	sc_attach_applet(sc, appctx);
	appctx->t->nice = __sc_strm(sc)->task->nice;
	applet_need_more_data(appctx);
	appctx_wakeup(appctx);

	sc->state = SC_ST_RDY;
	return appctx;
}

/*
 * This function performs a shutdown-read on a detached stream connector in a
 * connected or init state (it does nothing for other states). It either shuts
 * the read side or marks itself as closed. The buffer flags are updated to
 * reflect the new state. If the stream connector has SC_FL_NOHALF, we also
 * forward the close to the write side. The owner task is woken up if it exists.
 */
static void sc_app_shutr(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);

	if (ic->flags & CF_SHUTR)
		return;
	ic->flags |= CF_SHUTR;
	ic->rex = TICK_ETERNITY;

	if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
		return;

	if (sc_oc(sc)->flags & CF_SHUTW) {
		sc->state = SC_ST_DIS;
		if (sc->flags & SC_FL_ISBACK)
			__sc_strm(sc)->conn_exp = TICK_ETERNITY;
	}
	else if ((sc->flags & SC_FL_NOHALF) && channel_is_empty(ic)) {
		/* we want to immediately forward this close to the write side */
		return sc_app_shutw(sc);
	}

	/* note that if the task exists, it must unregister itself once it runs */
	if (!(sc->flags & SC_FL_DONT_WAKE))
		task_wakeup(sc_strm_task(sc), TASK_WOKEN_IO);
}

/*
 * This function performs a shutdown-write on a detached stream connector in a
 * connected or init state (it does nothing for other states). It either shuts
 * the write side or marks itself as closed. The buffer flags are updated to
 * reflect the new state. It does also close everything if the SC was marked as
 * being in error state. The owner task is woken up if it exists.
 */
static void sc_app_shutw(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);
	struct channel *oc = sc_oc(sc);

	oc->flags &= ~CF_SHUTW_NOW;
	if (oc->flags & CF_SHUTW)
		return;
	oc->flags |= CF_SHUTW;
	oc->wex = TICK_ETERNITY;

	if (tick_isset(sc->hcto)) {
		ic->rto = sc->hcto;
		ic->rex = tick_add(now_ms, ic->rto);
	}

	switch (sc->state) {
	case SC_ST_RDY:
	case SC_ST_EST:
		/* we have to shut before closing, otherwise some short messages
		 * may never leave the system, especially when there are remaining
		 * unread data in the socket input buffer, or when nolinger is set.
		 * However, if SC_FL_NOLINGER is explicitly set, we know there is
		 * no risk so we close both sides immediately.
		 */
		if (!sc_ep_test(sc, SE_FL_ERROR) && !(sc->flags & SC_FL_NOLINGER) &&
		    !(ic->flags & (CF_SHUTR|CF_DONT_READ)))
			return;

		__fallthrough;
	case SC_ST_CON:
	case SC_ST_CER:
	case SC_ST_QUE:
	case SC_ST_TAR:
		/* Note that none of these states may happen with applets */
		sc->state = SC_ST_DIS;
		__fallthrough;
	default:
		sc->flags &= ~SC_FL_NOLINGER;
		ic->flags |= CF_SHUTR;
		ic->rex = TICK_ETERNITY;
		if (sc->flags & SC_FL_ISBACK)
			__sc_strm(sc)->conn_exp = TICK_ETERNITY;
	}

	/* note that if the task exists, it must unregister itself once it runs */
	if (!(sc->flags & SC_FL_DONT_WAKE))
		task_wakeup(sc_strm_task(sc), TASK_WOKEN_IO);
}

/* default chk_rcv function for scheduled tasks */
static void sc_app_chk_rcv(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);

	DPRINTF(stderr, "%s: sc=%p, sc->state=%d ic->flags=%08x oc->flags=%08x\n",
		__FUNCTION__,
		sc, sc->state, ic->flags, sc_oc(sc)->flags);

	if (ic->pipe) {
		/* stop reading */
		sc_need_room(sc);
	}
	else {
		/* (re)start reading */
		if (!(sc->flags & SC_FL_DONT_WAKE))
			task_wakeup(sc_strm_task(sc), TASK_WOKEN_IO);
	}
}

/* default chk_snd function for scheduled tasks */
static void sc_app_chk_snd(struct stconn *sc)
{
	struct channel *oc = sc_oc(sc);

	DPRINTF(stderr, "%s: sc=%p, sc->state=%d ic->flags=%08x oc->flags=%08x\n",
		__FUNCTION__,
		sc, sc->state, sc_ic(sc)->flags, oc->flags);

	if (unlikely(sc->state != SC_ST_EST || (oc->flags & CF_SHUTW)))
		return;

	if (!sc_ep_test(sc, SE_FL_WAIT_DATA) ||  /* not waiting for data */
	    channel_is_empty(oc))                  /* called with nothing to send ! */
		return;

	/* Otherwise there are remaining data to be sent in the buffer,
	 * so we tell the handler.
	 */
	sc_ep_clr(sc, SE_FL_WAIT_DATA);
	if (!tick_isset(oc->wex))
		oc->wex = tick_add_ifset(now_ms, oc->wto);

	if (!(sc->flags & SC_FL_DONT_WAKE))
		task_wakeup(sc_strm_task(sc), TASK_WOKEN_IO);
}

/*
 * This function performs a shutdown-read on a stream connector attached to
 * a connection in a connected or init state (it does nothing for other
 * states). It either shuts the read side or marks itself as closed. The buffer
 * flags are updated to reflect the new state. If the stream connector has
 * SC_FL_NOHALF, we also forward the close to the write side. If a control
 * layer is defined, then it is supposed to be a socket layer and file
 * descriptors are then shutdown or closed accordingly. The function
 * automatically disables polling if needed.
 */
static void sc_app_shutr_conn(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);

	BUG_ON(!sc_conn(sc));

	if (ic->flags & CF_SHUTR)
		return;
	ic->flags |= CF_SHUTR;
	ic->rex = TICK_ETERNITY;

	if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
		return;

	if (sc_oc(sc)->flags & CF_SHUTW) {
		sc_conn_shut(sc);
		sc->state = SC_ST_DIS;
		if (sc->flags & SC_FL_ISBACK)
			__sc_strm(sc)->conn_exp = TICK_ETERNITY;
	}
	else if ((sc->flags & SC_FL_NOHALF) && channel_is_empty(ic)) {
		/* we want to immediately forward this close to the write side */
		return sc_app_shutw_conn(sc);
	}
}

/*
 * This function performs a shutdown-write on a stream connector attached to
 * a connection in a connected or init state (it does nothing for other
 * states). It either shuts the write side or marks itself as closed. The
 * buffer flags are updated to reflect the new state.  It does also close
 * everything if the SC was marked as being in error state. If there is a
 * data-layer shutdown, it is called.
 */
static void sc_app_shutw_conn(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);
	struct channel *oc = sc_oc(sc);

	BUG_ON(!sc_conn(sc));

	oc->flags &= ~CF_SHUTW_NOW;
	if (oc->flags & CF_SHUTW)
		return;
	oc->flags |= CF_SHUTW;
	oc->wex = TICK_ETERNITY;

	if (tick_isset(sc->hcto)) {
		ic->rto = sc->hcto;
		ic->rex = tick_add(now_ms, ic->rto);
	}

	switch (sc->state) {
	case SC_ST_RDY:
	case SC_ST_EST:
		/* we have to shut before closing, otherwise some short messages
		 * may never leave the system, especially when there are remaining
		 * unread data in the socket input buffer, or when nolinger is set.
		 * However, if SC_FL_NOLINGER is explicitly set, we know there is
		 * no risk so we close both sides immediately.
		 */

		if (sc_ep_test(sc, SE_FL_ERROR)) {
			/* quick close, the socket is already shut anyway */
		}
		else if (sc->flags & SC_FL_NOLINGER) {
			/* unclean data-layer shutdown, typically an aborted request
			 * or a forwarded shutdown from a client to a server due to
			 * option abortonclose. No need for the TLS layer to try to
			 * emit a shutdown message.
			 */
			sc_conn_shutw(sc, CO_SHW_SILENT);
		}
		else {
			/* clean data-layer shutdown. This only happens on the
			 * frontend side, or on the backend side when forwarding
			 * a client close in TCP mode or in HTTP TUNNEL mode
			 * while option abortonclose is set. We want the TLS
			 * layer to try to signal it to the peer before we close.
			 */
			sc_conn_shutw(sc, CO_SHW_NORMAL);

			if (!(ic->flags & (CF_SHUTR|CF_DONT_READ)))
				return;
		}

		__fallthrough;
	case SC_ST_CON:
		/* we may have to close a pending connection, and mark the
		 * response buffer as shutr
		 */
		sc_conn_shut(sc);
		__fallthrough;
	case SC_ST_CER:
	case SC_ST_QUE:
	case SC_ST_TAR:
		sc->state = SC_ST_DIS;
		__fallthrough;
	default:
		sc->flags &= ~SC_FL_NOLINGER;
		ic->flags |= CF_SHUTR;
		ic->rex = TICK_ETERNITY;
		if (sc->flags & SC_FL_ISBACK)
			__sc_strm(sc)->conn_exp = TICK_ETERNITY;
	}
}

/* This function is used for inter-stream connector calls. It is called by the
 * consumer to inform the producer side that it may be interested in checking
 * for free space in the buffer. Note that it intentionally does not update
 * timeouts, so that we can still check them later at wake-up. This function is
 * dedicated to connection-based stream connectors.
 */
static void sc_app_chk_rcv_conn(struct stconn *sc)
{
	BUG_ON(!sc_conn(sc));

	/* (re)start reading */
	if (sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
		tasklet_wakeup(sc->wait_event.tasklet);
}


/* This function is used for inter-stream connector calls. It is called by the
 * producer to inform the consumer side that it may be interested in checking
 * for data in the buffer. Note that it intentionally does not update timeouts,
 * so that we can still check them later at wake-up.
 */
static void sc_app_chk_snd_conn(struct stconn *sc)
{
	struct channel *oc = sc_oc(sc);

	BUG_ON(!sc_conn(sc));

	if (unlikely(!sc_state_in(sc->state, SC_SB_RDY|SC_SB_EST) ||
	    (oc->flags & CF_SHUTW)))
		return;

	if (unlikely(channel_is_empty(oc)))  /* called with nothing to send ! */
		return;

	if (!oc->pipe &&                          /* spliced data wants to be forwarded ASAP */
	    !sc_ep_test(sc, SE_FL_WAIT_DATA))       /* not waiting for data */
		return;

	if (!(sc->wait_event.events & SUB_RETRY_SEND) && !channel_is_empty(sc_oc(sc)))
		sc_conn_send(sc);

	if (sc_ep_test(sc, SE_FL_ERROR | SE_FL_ERR_PENDING) || sc_is_conn_error(sc)) {
		/* Write error on the file descriptor */
		if (sc->state >= SC_ST_CON && sc_ep_test(sc, SE_FL_EOS))
			sc_ep_set(sc, SE_FL_ERROR);
		goto out_wakeup;
	}

	/* OK, so now we know that some data might have been sent, and that we may
	 * have to poll first. We have to do that too if the buffer is not empty.
	 */
	if (channel_is_empty(oc)) {
		/* the connection is established but we can't write. Either the
		 * buffer is empty, or we just refrain from sending because the
		 * ->o limit was reached. Maybe we just wrote the last
		 * chunk and need to close.
		 */
		if (((oc->flags & (CF_SHUTW|CF_AUTO_CLOSE|CF_SHUTW_NOW)) ==
		     (CF_AUTO_CLOSE|CF_SHUTW_NOW)) &&
		    sc_state_in(sc->state, SC_SB_RDY|SC_SB_EST)) {
			sc_shutw(sc);
			goto out_wakeup;
		}

		if ((oc->flags & (CF_SHUTW|CF_SHUTW_NOW)) == 0)
			sc_ep_set(sc, SE_FL_WAIT_DATA);
		oc->wex = TICK_ETERNITY;
	}
	else {
		/* Otherwise there are remaining data to be sent in the buffer,
		 * which means we have to poll before doing so.
		 */
		sc_ep_clr(sc, SE_FL_WAIT_DATA);
		if (!tick_isset(oc->wex))
			oc->wex = tick_add_ifset(now_ms, oc->wto);
	}

	if (likely(oc->flags & CF_WRITE_ACTIVITY)) {
		struct channel *ic = sc_ic(sc);

		/* update timeout if we have written something */
		if ((oc->flags & (CF_SHUTW|CF_WRITE_PARTIAL)) == CF_WRITE_PARTIAL &&
		    !channel_is_empty(oc))
			oc->wex = tick_add_ifset(now_ms, oc->wto);

		if (tick_isset(ic->rex) && !(sc->flags & SC_FL_INDEP_STR)) {
			/* Note: to prevent the client from expiring read timeouts
			 * during writes, we refresh it. We only do this if the
			 * interface is not configured for "independent streams",
			 * because for some applications it's better not to do this,
			 * for instance when continuously exchanging small amounts
			 * of data which can full the socket buffers long before a
			 * write timeout is detected.
			 */
			ic->rex = tick_add_ifset(now_ms, ic->rto);
		}
	}

	/* in case of special condition (error, shutdown, end of write...), we
	 * have to notify the task.
	 */
	if (likely((oc->flags & (CF_WRITE_NULL|CF_WRITE_ERROR|CF_SHUTW)) ||
	          ((oc->flags & CF_WAKE_WRITE) &&
	           ((channel_is_empty(oc) && !oc->to_forward) ||
	            !sc_state_in(sc->state, SC_SB_EST))))) {
	out_wakeup:
		if (!(sc->flags & SC_FL_DONT_WAKE))
			task_wakeup(sc_strm_task(sc), TASK_WOKEN_IO);
	}
}

/*
 * This function performs a shutdown-read on a stream connector attached to an
 * applet in a connected or init state (it does nothing for other states). It
 * either shuts the read side or marks itself as closed. The buffer flags are
 * updated to reflect the new state. If the stream connector has SC_FL_NOHALF,
 * we also forward the close to the write side. The owner task is woken up if
 * it exists.
 */
static void sc_app_shutr_applet(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);

	BUG_ON(!sc_appctx(sc));

	if (ic->flags & CF_SHUTR)
		return;
	ic->flags |= CF_SHUTR;
	ic->rex = TICK_ETERNITY;

	/* Note: on shutr, we don't call the applet */

	if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
		return;

	if (sc_oc(sc)->flags & CF_SHUTW) {
		appctx_shut(__sc_appctx(sc));
		sc->state = SC_ST_DIS;
		if (sc->flags & SC_FL_ISBACK)
			__sc_strm(sc)->conn_exp = TICK_ETERNITY;
	}
	else if ((sc->flags & SC_FL_NOHALF) && channel_is_empty(ic)) {
		/* we want to immediately forward this close to the write side */
		return sc_app_shutw_applet(sc);
	}
}

/*
 * This function performs a shutdown-write on a stream connector attached to an
 * applet in a connected or init state (it does nothing for other states). It
 * either shuts the write side or marks itself as closed. The buffer flags are
 * updated to reflect the new state. It does also close everything if the SI
 * was marked as being in error state. The owner task is woken up if it exists.
 */
static void sc_app_shutw_applet(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);
	struct channel *oc = sc_oc(sc);

	BUG_ON(!sc_appctx(sc));

	oc->flags &= ~CF_SHUTW_NOW;
	if (oc->flags & CF_SHUTW)
		return;
	oc->flags |= CF_SHUTW;
	oc->wex = TICK_ETERNITY;

	if (tick_isset(sc->hcto)) {
		ic->rto = sc->hcto;
		ic->rex = tick_add(now_ms, ic->rto);
	}

	/* on shutw we always wake the applet up */
	appctx_wakeup(__sc_appctx(sc));

	switch (sc->state) {
	case SC_ST_RDY:
	case SC_ST_EST:
		/* we have to shut before closing, otherwise some short messages
		 * may never leave the system, especially when there are remaining
		 * unread data in the socket input buffer, or when nolinger is set.
		 * However, if SC_FL_NOLINGER is explicitly set, we know there is
		 * no risk so we close both sides immediately.
		 */
		if (!sc_ep_test(sc, SE_FL_ERROR) && !(sc->flags & SC_FL_NOLINGER) &&
		    !(ic->flags & (CF_SHUTR|CF_DONT_READ)))
			return;

		__fallthrough;
	case SC_ST_CON:
	case SC_ST_CER:
	case SC_ST_QUE:
	case SC_ST_TAR:
		/* Note that none of these states may happen with applets */
		appctx_shut(__sc_appctx(sc));
		sc->state = SC_ST_DIS;
		__fallthrough;
	default:
		sc->flags &= ~SC_FL_NOLINGER;
		ic->flags |= CF_SHUTR;
		ic->rex = TICK_ETERNITY;
		if (sc->flags & SC_FL_ISBACK)
			__sc_strm(sc)->conn_exp = TICK_ETERNITY;
	}
}

/* chk_rcv function for applets */
static void sc_app_chk_rcv_applet(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);

	BUG_ON(!sc_appctx(sc));

	DPRINTF(stderr, "%s: sc=%p, sc->state=%d ic->flags=%08x oc->flags=%08x\n",
		__FUNCTION__,
		sc, sc->state, ic->flags, sc_oc(sc)->flags);

	if (!ic->pipe) {
		/* (re)start reading */
		appctx_wakeup(__sc_appctx(sc));
	}
}

/* chk_snd function for applets */
static void sc_app_chk_snd_applet(struct stconn *sc)
{
	struct channel *oc = sc_oc(sc);

	BUG_ON(!sc_appctx(sc));

	DPRINTF(stderr, "%s: sc=%p, sc->state=%d ic->flags=%08x oc->flags=%08x\n",
		__FUNCTION__,
		sc, sc->state, sc_ic(sc)->flags, oc->flags);

	if (unlikely(sc->state != SC_ST_EST || (oc->flags & CF_SHUTW)))
		return;

	/* we only wake the applet up if it was waiting for some data  and is ready to consume it */
	if (!sc_ep_test(sc, SE_FL_WAIT_DATA) || sc_ep_test(sc, SE_FL_WONT_CONSUME))
		return;

	if (!tick_isset(oc->wex))
		oc->wex = tick_add_ifset(now_ms, oc->wto);

	if (!channel_is_empty(oc)) {
		/* (re)start sending */
		appctx_wakeup(__sc_appctx(sc));
	}
}


/* This function is designed to be called from within the stream handler to
 * update the input channel's expiration timer and the stream connector's
 * Rx flags based on the channel's flags. It needs to be called only once
 * after the channel's flags have settled down, and before they are cleared,
 * though it doesn't harm to call it as often as desired (it just slightly
 * hurts performance). It must not be called from outside of the stream
 * handler, as what it does will be used to compute the stream task's
 * expiration.
 */
void sc_update_rx(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);

	if (ic->flags & CF_SHUTR)
		return;

	/* Read not closed, update FD status and timeout for reads */
	if (ic->flags & CF_DONT_READ)
		sc_wont_read(sc);
	else
		sc_will_read(sc);

	if (!channel_is_empty(ic) || !channel_may_recv(ic)) {
		/* stop reading, imposed by channel's policy or contents */
		sc_need_room(sc);
	}
	else {
		/* (re)start reading and update timeout. Note: we don't recompute the timeout
		 * every time we get here, otherwise it would risk never to expire. We only
		 * update it if is was not yet set. The stream socket handler will already
		 * have updated it if there has been a completed I/O.
		 */
		sc_have_room(sc);
	}
	if (sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM))
		ic->rex = TICK_ETERNITY;
	else if (!(ic->flags & CF_READ_NOEXP) && !tick_isset(ic->rex))
		ic->rex = tick_add_ifset(now_ms, ic->rto);

	sc_chk_rcv(sc);
}

/* This function is designed to be called from within the stream handler to
 * update the output channel's expiration timer and the stream connector's
 * Tx flags based on the channel's flags. It needs to be called only once
 * after the channel's flags have settled down, and before they are cleared,
 * though it doesn't harm to call it as often as desired (it just slightly
 * hurts performance). It must not be called from outside of the stream
 * handler, as what it does will be used to compute the stream task's
 * expiration.
 */
void sc_update_tx(struct stconn *sc)
{
	struct channel *oc = sc_oc(sc);
	struct channel *ic = sc_ic(sc);

	if (oc->flags & CF_SHUTW)
		return;

	/* Write not closed, update FD status and timeout for writes */
	if (channel_is_empty(oc)) {
		/* stop writing */
		if (!sc_ep_test(sc, SE_FL_WAIT_DATA)) {
			if ((oc->flags & CF_SHUTW_NOW) == 0)
				sc_ep_set(sc, SE_FL_WAIT_DATA);
			oc->wex = TICK_ETERNITY;
		}
		return;
	}

	/* (re)start writing and update timeout. Note: we don't recompute the timeout
	 * every time we get here, otherwise it would risk never to expire. We only
	 * update it if is was not yet set. The stream socket handler will already
	 * have updated it if there has been a completed I/O.
	 */
	sc_ep_clr(sc, SE_FL_WAIT_DATA);
	if (!tick_isset(oc->wex)) {
		oc->wex = tick_add_ifset(now_ms, oc->wto);
		if (tick_isset(ic->rex) && !(sc->flags & SC_FL_INDEP_STR)) {
			/* Note: depending on the protocol, we don't know if we're waiting
			 * for incoming data or not. So in order to prevent the socket from
			 * expiring read timeouts during writes, we refresh the read timeout,
			 * except if it was already infinite or if we have explicitly setup
			 * independent streams.
			 */
			ic->rex = tick_add_ifset(now_ms, ic->rto);
		}
	}
}

/* This function is the equivalent to sc_update() except that it's
 * designed to be called from outside the stream handlers, typically the lower
 * layers (applets, connections) after I/O completion. After updating the stream
 * interface and timeouts, it will try to forward what can be forwarded, then to
 * wake the associated task up if an important event requires special handling.
 * It may update SE_FL_WAIT_DATA and/or SC_FL_NEED_ROOM, that the callers are
 * encouraged to watch to take appropriate action.
 * It should not be called from within the stream itself, sc_update()
 * is designed for this.
 */
static void sc_notify(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);
	struct channel *oc = sc_oc(sc);
	struct stconn *sco = sc_opposite(sc);
	struct task *task = sc_strm_task(sc);

	/* process consumer side */
	if (channel_is_empty(oc)) {
		struct connection *conn = sc_conn(sc);

		if (((oc->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW) &&
		    (sc->state == SC_ST_EST) && (!conn || !(conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS))))
			sc_shutw(sc);
		oc->wex = TICK_ETERNITY;
	}

	/* indicate that we may be waiting for data from the output channel or
	 * we're about to close and can't expect more data if SHUTW_NOW is there.
	 */
	if (!(oc->flags & (CF_SHUTW|CF_SHUTW_NOW)))
		sc_ep_set(sc, SE_FL_WAIT_DATA);
	else if ((oc->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW)
		sc_ep_clr(sc, SE_FL_WAIT_DATA);

	/* update OC timeouts and wake the other side up if it's waiting for room */
	if (oc->flags & CF_WRITE_ACTIVITY) {
		if ((oc->flags & (CF_SHUTW|CF_WRITE_PARTIAL)) == CF_WRITE_PARTIAL &&
		    !channel_is_empty(oc))
			if (tick_isset(oc->wex))
				oc->wex = tick_add_ifset(now_ms, oc->wto);

		if (!(sc->flags & SC_FL_INDEP_STR))
			if (tick_isset(ic->rex))
				ic->rex = tick_add_ifset(now_ms, ic->rto);
	}

	if (oc->flags & CF_DONT_READ)
		sc_wont_read(sco);
	else
		sc_will_read(sco);

	/* Notify the other side when we've injected data into the IC that
	 * needs to be forwarded. We can do fast-forwarding as soon as there
	 * are output data, but we avoid doing this if some of the data are
	 * not yet scheduled for being forwarded, because it is very likely
	 * that it will be done again immediately afterwards once the following
	 * data are parsed (eg: HTTP chunking). We only clear SC_FL_NEED_ROOM
	 * once we've emptied *some* of the output buffer, and not just when
	 * there is available room, because applets are often forced to stop
	 * before the buffer is full. We must not stop based on input data
	 * alone because an HTTP parser might need more data to complete the
	 * parsing.
	 */
	if (!channel_is_empty(ic) &&
	    sc_ep_test(sco, SE_FL_WAIT_DATA) &&
	    (!(ic->flags & CF_EXPECT_MORE) || c_full(ic) || ci_data(ic) == 0 || ic->pipe)) {
		int new_len, last_len;

		last_len = co_data(ic);
		if (ic->pipe)
			last_len += ic->pipe->data;

		sc_chk_snd(sco);

		new_len = co_data(ic);
		if (ic->pipe)
			new_len += ic->pipe->data;

		/* check if the consumer has freed some space either in the
		 * buffer or in the pipe.
		 */
		if (new_len < last_len)
			sc_have_room(sc);
	}

	if (!(ic->flags & CF_DONT_READ))
		sc_will_read(sc);

	sc_chk_rcv(sc);
	sc_chk_rcv(sco);

	if (ic->flags & CF_SHUTR || sc_ep_test(sc, SE_FL_APPLET_NEED_CONN) ||
	    (sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM))) {
		ic->rex = TICK_ETERNITY;
	}
	else if ((ic->flags & (CF_SHUTR|CF_READ_PARTIAL)) == CF_READ_PARTIAL) {
		/* we must re-enable reading if sc_chk_snd() has freed some space */
		if (!(ic->flags & CF_READ_NOEXP) && tick_isset(ic->rex))
			ic->rex = tick_add_ifset(now_ms, ic->rto);
	}

	/* wake the task up only when needed */
	if (/* changes on the production side */
	    (ic->flags & (CF_READ_NULL|CF_READ_ERROR)) ||
	    !sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST) ||
	    sc_ep_test(sc, SE_FL_ERROR) ||
	    ((ic->flags & CF_READ_PARTIAL) &&
	     ((ic->flags & CF_EOI) || !ic->to_forward || sco->state != SC_ST_EST)) ||

	    /* changes on the consumption side */
	    (oc->flags & (CF_WRITE_NULL|CF_WRITE_ERROR)) ||
	    ((oc->flags & CF_WRITE_ACTIVITY) &&
	     ((oc->flags & CF_SHUTW) ||
	      (((oc->flags & CF_WAKE_WRITE) ||
		!(oc->flags & (CF_AUTO_CLOSE|CF_SHUTW_NOW|CF_SHUTW))) &&
	       (sco->state != SC_ST_EST ||
	        (channel_is_empty(oc) && !oc->to_forward)))))) {
		task_wakeup(task, TASK_WOKEN_IO);
	}
	else {
		/* Update expiration date for the task and requeue it */
		task->expire = tick_first((tick_is_expired(task->expire, now_ms) ? 0 : task->expire),
					  tick_first(tick_first(ic->rex, ic->wex),
						     tick_first(oc->rex, oc->wex)));

		task->expire = tick_first(task->expire, ic->analyse_exp);
		task->expire = tick_first(task->expire, oc->analyse_exp);
		task->expire = tick_first(task->expire, __sc_strm(sc)->conn_exp);

		task_queue(task);
	}
	if (ic->flags & CF_READ_ACTIVITY)
		ic->flags &= ~CF_READ_DONTWAIT;
}

/*
 * This function propagates a null read received on a socket-based connection.
 * It updates the stream connector. If the stream connector has SC_FL_NOHALF,
 * the close is also forwarded to the write side as an abort.
 */
static void sc_conn_read0(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);
	struct channel *oc = sc_oc(sc);

	BUG_ON(!sc_conn(sc));

	if (ic->flags & CF_SHUTR)
		return;
	ic->flags |= CF_SHUTR;
	ic->rex = TICK_ETERNITY;

	if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
		return;

	if (oc->flags & CF_SHUTW)
		goto do_close;

	if ((sc->flags & SC_FL_NOHALF) && channel_is_empty(ic)) {
		/* we want to immediately forward this close to the write side */
		/* force flag on ssl to keep stream in cache */
		sc_conn_shutw(sc, CO_SHW_SILENT);
		goto do_close;
	}

	/* otherwise that's just a normal read shutdown */
	return;

 do_close:
	/* OK we completely close the socket here just as if we went through sc_shut[rw]() */
	sc_conn_shut(sc);

	oc->flags &= ~CF_SHUTW_NOW;
	oc->flags |= CF_SHUTW;
	oc->wex = TICK_ETERNITY;

	sc->state = SC_ST_DIS;
	if (sc->flags & SC_FL_ISBACK)
		__sc_strm(sc)->conn_exp = TICK_ETERNITY;
	return;
}

/*
 * This is the callback which is called by the connection layer to receive data
 * into the buffer from the connection. It iterates over the mux layer's
 * rcv_buf function.
 */
static int sc_conn_recv(struct stconn *sc)
{
	struct connection *conn = __sc_conn(sc);
	struct channel *ic = sc_ic(sc);
	int ret, max, cur_read = 0;
	int read_poll = MAX_READ_POLL_LOOPS;
	int flags = 0;

	/* If not established yet, do nothing. */
	if (sc->state != SC_ST_EST)
		return 0;

	/* If another call to sc_conn_recv() failed, and we subscribed to
	 * recv events already, give up now.
	 */
	if (sc->wait_event.events & SUB_RETRY_RECV)
		return 0;

	/* maybe we were called immediately after an asynchronous shutr */
	if (ic->flags & CF_SHUTR)
		return 1;

	/* we must wait because the mux is not installed yet */
	if (!conn->mux)
		return 0;

	/* stop here if we reached the end of data */
	if (sc_ep_test(sc, SE_FL_EOS))
		goto end_recv;

	/* stop immediately on errors. Note that we DON'T want to stop on
	 * POLL_ERR, as the poller might report a write error while there
	 * are still data available in the recv buffer. This typically
	 * happens when we send too large a request to a backend server
	 * which rejects it before reading it all.
	 */
	if (!sc_ep_test(sc, SE_FL_RCV_MORE)) {
		if (!conn_xprt_ready(conn))
			return 0;
		if (sc_ep_test(sc, SE_FL_ERROR))
			goto end_recv;
	}

	/* prepare to detect if the mux needs more room */
	sc_ep_clr(sc, SE_FL_WANT_ROOM);

	if ((ic->flags & (CF_STREAMER | CF_STREAMER_FAST)) && !co_data(ic) &&
	    global.tune.idle_timer &&
	    (unsigned short)(now_ms - ic->last_read) >= global.tune.idle_timer) {
		/* The buffer was empty and nothing was transferred for more
		 * than one second. This was caused by a pause and not by
		 * congestion. Reset any streaming mode to reduce latency.
		 */
		ic->xfer_small = 0;
		ic->xfer_large = 0;
		ic->flags &= ~(CF_STREAMER | CF_STREAMER_FAST);
	}

	/* First, let's see if we may splice data across the channel without
	 * using a buffer.
	 */
	if (sc_ep_test(sc, SE_FL_MAY_SPLICE) &&
	    (ic->pipe || ic->to_forward >= MIN_SPLICE_FORWARD) &&
	    ic->flags & CF_KERN_SPLICING) {
		if (c_data(ic)) {
			/* We're embarrassed, there are already data pending in
			 * the buffer and we don't want to have them at two
			 * locations at a time. Let's indicate we need some
			 * place and ask the consumer to hurry.
			 */
			flags |= CO_RFL_BUF_FLUSH;
			goto abort_splice;
		}

		if (unlikely(ic->pipe == NULL)) {
			if (pipes_used >= global.maxpipes || !(ic->pipe = get_pipe())) {
				ic->flags &= ~CF_KERN_SPLICING;
				goto abort_splice;
			}
		}

		ret = conn->mux->rcv_pipe(sc, ic->pipe, ic->to_forward);
		if (ret < 0) {
			/* splice not supported on this end, let's disable it */
			ic->flags &= ~CF_KERN_SPLICING;
			goto abort_splice;
		}

		if (ret > 0) {
			if (ic->to_forward != CHN_INFINITE_FORWARD)
				ic->to_forward -= ret;
			ic->total += ret;
			cur_read += ret;
			ic->flags |= CF_READ_PARTIAL;
		}

		if (sc_ep_test(sc, SE_FL_EOS | SE_FL_ERROR))
			goto end_recv;

		if (conn->flags & CO_FL_WAIT_ROOM) {
			/* the pipe is full or we have read enough data that it
			 * could soon be full. Let's stop before needing to poll.
			 */
			sc_need_room(sc);
			goto done_recv;
		}

		/* splice not possible (anymore), let's go on on standard copy */
	}

 abort_splice:
	if (ic->pipe && unlikely(!ic->pipe->data)) {
		put_pipe(ic->pipe);
		ic->pipe = NULL;
	}

	if (ic->pipe && ic->to_forward && !(flags & CO_RFL_BUF_FLUSH) && sc_ep_test(sc, SE_FL_MAY_SPLICE)) {
		/* don't break splicing by reading, but still call rcv_buf()
		 * to pass the flag.
		 */
		goto done_recv;
	}

	/* now we'll need a input buffer for the stream */
	if (!sc_alloc_ibuf(sc, &(__sc_strm(sc)->buffer_wait)))
		goto end_recv;

	/* For an HTX stream, if the buffer is stuck (no output data with some
	 * input data) and if the HTX message is fragmented or if its free space
	 * wraps, we force an HTX deframentation. It is a way to have a
	 * contiguous free space nad to let the mux to copy as much data as
	 * possible.
	 *
	 * NOTE: A possible optim may be to let the mux decides if defrag is
	 *       required or not, depending on amount of data to be xferred.
	 */
	if (IS_HTX_STRM(__sc_strm(sc)) && !co_data(ic)) {
		struct htx *htx = htxbuf(&ic->buf);

		if (htx_is_not_empty(htx) && ((htx->flags & HTX_FL_FRAGMENTED) || htx_space_wraps(htx)))
			htx_defrag(htx, NULL, 0);
	}

	/* Instruct the mux it must subscribed for read events */
	flags |= ((!conn_is_back(conn) && (__sc_strm(sc)->be->options & PR_O_ABRT_CLOSE)) ? CO_RFL_KEEP_RECV : 0);

	/* Important note : if we're called with POLL_IN|POLL_HUP, it means the read polling
	 * was enabled, which implies that the recv buffer was not full. So we have a guarantee
	 * that if such an event is not handled above in splice, it will be handled here by
	 * recv().
	 */
	while (sc_ep_test(sc, SE_FL_RCV_MORE) ||
	       (!(conn->flags & CO_FL_HANDSHAKE) &&
	       (!sc_ep_test(sc, SE_FL_ERROR | SE_FL_EOS)) && !(ic->flags & CF_SHUTR))) {
		int cur_flags = flags;

		/* Compute transient CO_RFL_* flags */
		if (co_data(ic)) {
			cur_flags |= (CO_RFL_BUF_WET | CO_RFL_BUF_NOT_STUCK);
		}

		/* <max> may be null. This is the mux responsibility to set
		 * SE_FL_RCV_MORE on the SC if more space is needed.
		 */
		max = channel_recv_max(ic);
		ret = conn->mux->rcv_buf(sc, &ic->buf, max, cur_flags);

		if (sc_ep_test(sc, SE_FL_WANT_ROOM)) {
			/* SE_FL_WANT_ROOM must not be reported if the channel's
			 * buffer is empty.
			 */
			BUG_ON(c_empty(ic));

			sc_need_room(sc);
			/* Add READ_PARTIAL because some data are pending but
			 * cannot be xferred to the channel
			 */
			ic->flags |= CF_READ_PARTIAL;
		}

		if (ret <= 0) {
			/* if we refrained from reading because we asked for a
			 * flush to satisfy rcv_pipe(), we must not subscribe
			 * and instead report that there's not enough room
			 * here to proceed.
			 */
			if (flags & CO_RFL_BUF_FLUSH)
				sc_need_room(sc);
			break;
		}

		cur_read += ret;

		/* if we're allowed to directly forward data, we must update ->o */
		if (ic->to_forward && !(ic->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
			unsigned long fwd = ret;
			if (ic->to_forward != CHN_INFINITE_FORWARD) {
				if (fwd > ic->to_forward)
					fwd = ic->to_forward;
				ic->to_forward -= fwd;
			}
			c_adv(ic, fwd);
		}

		ic->flags |= CF_READ_PARTIAL;
		ic->total += ret;

		/* End-of-input reached, we can leave. In this case, it is
		 * important to break the loop to not block the SC because of
		 * the channel's policies.This way, we are still able to receive
		 * shutdowns.
		 */
		if (sc_ep_test(sc, SE_FL_EOI))
			break;

		if ((ic->flags & CF_READ_DONTWAIT) || --read_poll <= 0) {
			/* we're stopped by the channel's policy */
			sc_wont_read(sc);
			break;
		}

		/* if too many bytes were missing from last read, it means that
		 * it's pointless trying to read again because the system does
		 * not have them in buffers.
		 */
		if (ret < max) {
			/* if a streamer has read few data, it may be because we
			 * have exhausted system buffers. It's not worth trying
			 * again.
			 */
			if (ic->flags & CF_STREAMER) {
				/* we're stopped by the channel's policy */
				sc_wont_read(sc);
				break;
			}

			/* if we read a large block smaller than what we requested,
			 * it's almost certain we'll never get anything more.
			 */
			if (ret >= global.tune.recv_enough) {
				/* we're stopped by the channel's policy */
				sc_wont_read(sc);
				break;
			}
		}

		/* if we are waiting for more space, don't try to read more data
		 * right now.
		 */
		if (sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM))
			break;
	} /* while !flags */

 done_recv:
	if (cur_read) {
		if ((ic->flags & (CF_STREAMER | CF_STREAMER_FAST)) &&
		    (cur_read <= ic->buf.size / 2)) {
			ic->xfer_large = 0;
			ic->xfer_small++;
			if (ic->xfer_small >= 3) {
				/* we have read less than half of the buffer in
				 * one pass, and this happened at least 3 times.
				 * This is definitely not a streamer.
				 */
				ic->flags &= ~(CF_STREAMER | CF_STREAMER_FAST);
			}
			else if (ic->xfer_small >= 2) {
				/* if the buffer has been at least half full twice,
				 * we receive faster than we send, so at least it
				 * is not a "fast streamer".
				 */
				ic->flags &= ~CF_STREAMER_FAST;
			}
		}
		else if (!(ic->flags & CF_STREAMER_FAST) &&
			 (cur_read >= ic->buf.size - global.tune.maxrewrite)) {
			/* we read a full buffer at once */
			ic->xfer_small = 0;
			ic->xfer_large++;
			if (ic->xfer_large >= 3) {
				/* we call this buffer a fast streamer if it manages
				 * to be filled in one call 3 consecutive times.
				 */
				ic->flags |= (CF_STREAMER | CF_STREAMER_FAST);
			}
		}
		else {
			ic->xfer_small = 0;
			ic->xfer_large = 0;
		}
		ic->last_read = now_ms;
	}

 end_recv:
	ret = (cur_read != 0);

	/* Report EOI on the channel if it was reached from the mux point of
	 * view. */
	if (sc_ep_test(sc, SE_FL_EOI) && !(ic->flags & CF_EOI)) {
		ic->flags |= (CF_EOI|CF_READ_PARTIAL);
		ret = 1;
	}

	if (sc_ep_test(sc, SE_FL_ERROR))
		ret = 1;
	else if (sc_ep_test(sc, SE_FL_EOS)) {
		/* we received a shutdown */
		ic->flags |= CF_READ_NULL;
		if (ic->flags & CF_AUTO_CLOSE)
			channel_shutw_now(ic);
		sc_conn_read0(sc);
		ret = 1;
	}
	else if (!(sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM)) &&
		 !(ic->flags & CF_SHUTR)) {
		/* Subscribe to receive events if we're blocking on I/O */
		conn->mux->subscribe(sc, SUB_RETRY_RECV, &sc->wait_event);
		se_have_no_more_data(sc->sedesc);
	} else {
		se_have_more_data(sc->sedesc);
		ret = 1;
	}
	return ret;
}

/* This tries to perform a synchronous receive on the stream connector to
 * try to collect last arrived data. In practice it's only implemented on
 * stconns. Returns 0 if nothing was done, non-zero if new data or a
 * shutdown were collected. This may result on some delayed receive calls
 * to be programmed and performed later, though it doesn't provide any
 * such guarantee.
 */
int sc_conn_sync_recv(struct stconn *sc)
{
	if (!sc_state_in(sc->state, SC_SB_RDY|SC_SB_EST))
		return 0;

	if (!sc_mux_ops(sc))
		return 0; // only stconns are supported

	if (sc->wait_event.events & SUB_RETRY_RECV)
		return 0; // already subscribed

	if (!sc_is_recv_allowed(sc))
		return 0; // already failed

	return sc_conn_recv(sc);
}

/*
 * This function is called to send buffer data to a stream socket.
 * It calls the mux layer's snd_buf function. It relies on the
 * caller to commit polling changes. The caller should check conn->flags
 * for errors.
 */
static int sc_conn_send(struct stconn *sc)
{
	struct connection *conn = __sc_conn(sc);
	struct stream *s = __sc_strm(sc);
	struct channel *oc = sc_oc(sc);
	int ret;
	int did_send = 0;

	if (sc_ep_test(sc, SE_FL_ERROR | SE_FL_ERR_PENDING) || sc_is_conn_error(sc)) {
		/* We're probably there because the tasklet was woken up,
		 * but process_stream() ran before, detected there were an
		 * error and put the SC back to SC_ST_TAR. There's still
		 * CO_FL_ERROR on the connection but we don't want to add
		 * SE_FL_ERROR back, so give up
		 */
		if (sc->state < SC_ST_CON)
			return 0;
		if (sc_ep_test(sc, SE_FL_EOS))
		    sc_ep_set(sc, SE_FL_ERROR);
		return 1;
	}

	/* We're already waiting to be able to send, give up */
	if (sc->wait_event.events & SUB_RETRY_SEND)
		return 0;

	/* we might have been called just after an asynchronous shutw */
	if (oc->flags & CF_SHUTW)
		return 1;

	/* we must wait because the mux is not installed yet */
	if (!conn->mux)
		return 0;

	if (oc->pipe && conn->xprt->snd_pipe && conn->mux->snd_pipe) {
		ret = conn->mux->snd_pipe(sc, oc->pipe);
		if (ret > 0)
			did_send = 1;

		if (!oc->pipe->data) {
			put_pipe(oc->pipe);
			oc->pipe = NULL;
		}

		if (oc->pipe)
			goto end;
	}

	/* At this point, the pipe is empty, but we may still have data pending
	 * in the normal buffer.
	 */
	if (co_data(oc)) {
		/* when we're here, we already know that there is no spliced
		 * data left, and that there are sendable buffered data.
		 */

		/* check if we want to inform the kernel that we're interested in
		 * sending more data after this call. We want this if :
		 *  - we're about to close after this last send and want to merge
		 *    the ongoing FIN with the last segment.
		 *  - we know we can't send everything at once and must get back
		 *    here because of unaligned data
		 *  - there is still a finite amount of data to forward
		 * The test is arranged so that the most common case does only 2
		 * tests.
		 */
		unsigned int send_flag = 0;

		if ((!(oc->flags & (CF_NEVER_WAIT|CF_SEND_DONTWAIT)) &&
		     ((oc->to_forward && oc->to_forward != CHN_INFINITE_FORWARD) ||
		      (oc->flags & CF_EXPECT_MORE) ||
		      (IS_HTX_STRM(s) &&
		       (!(oc->flags & (CF_EOI|CF_SHUTR)) && htx_expect_more(htxbuf(&oc->buf)))))) ||
		    ((oc->flags & CF_ISRESP) &&
		     ((oc->flags & (CF_AUTO_CLOSE|CF_SHUTW_NOW)) == (CF_AUTO_CLOSE|CF_SHUTW_NOW))))
			send_flag |= CO_SFL_MSG_MORE;

		if (oc->flags & CF_STREAMER)
			send_flag |= CO_SFL_STREAMER;

		if (s->txn && s->txn->flags & TX_L7_RETRY && !b_data(&s->txn->l7_buffer)) {
			/* If we want to be able to do L7 retries, copy
			 * the data we're about to send, so that we are able
			 * to resend them if needed
			 */
			/* Try to allocate a buffer if we had none.
			 * If it fails, the next test will just
			 * disable the l7 retries by setting
			 * l7_conn_retries to 0.
			 */
			if (s->txn->req.msg_state != HTTP_MSG_DONE)
				s->txn->flags &= ~TX_L7_RETRY;
			else {
				if (b_alloc(&s->txn->l7_buffer) == NULL)
					s->txn->flags &= ~TX_L7_RETRY;
				else {
					memcpy(b_orig(&s->txn->l7_buffer),
					       b_orig(&oc->buf),
					       b_size(&oc->buf));
					s->txn->l7_buffer.head = co_data(oc);
					b_add(&s->txn->l7_buffer, co_data(oc));
				}

			}
		}

		ret = conn->mux->snd_buf(sc, &oc->buf, co_data(oc), send_flag);
		if (ret > 0) {
			did_send = 1;
			c_rew(oc, ret);
			c_realign_if_empty(oc);

			if (!co_data(oc)) {
				/* Always clear both flags once everything has been sent, they're one-shot */
				oc->flags &= ~(CF_EXPECT_MORE | CF_SEND_DONTWAIT);
			}
			/* if some data remain in the buffer, it's only because the
			 * system buffers are full, we will try next time.
			 */
		}
	}

 end:
	if (did_send) {
		oc->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA;
		if (sc->state == SC_ST_CON)
			sc->state = SC_ST_RDY;

		sc_have_room(sc_opposite(sc));
	}

	if (sc_ep_test(sc, SE_FL_ERROR | SE_FL_ERR_PENDING)) {
		if (sc_ep_test(sc, SE_FL_EOS))
		    sc_ep_set(sc, SE_FL_ERROR);
		return 1;
	}

	/* We couldn't send all of our data, let the mux know we'd like to send more */
	if (!channel_is_empty(oc))
		conn->mux->subscribe(sc, SUB_RETRY_SEND, &sc->wait_event);
	return did_send;
}

/* perform a synchronous send() for the stream connector. The CF_WRITE_NULL and
 * CF_WRITE_PARTIAL flags are cleared prior to the attempt, and will possibly
 * be updated in case of success.
 */
void sc_conn_sync_send(struct stconn *sc)
{
	struct channel *oc = sc_oc(sc);

	oc->flags &= ~(CF_WRITE_NULL|CF_WRITE_PARTIAL);

	if (oc->flags & CF_SHUTW)
		return;

	if (channel_is_empty(oc))
		return;

	if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
		return;

	if (!sc_mux_ops(sc))
		return;

	sc_conn_send(sc);
}

/* Called by I/O handlers after completion.. It propagates
 * connection flags to the stream connector, updates the stream (which may or
 * may not take this opportunity to try to forward data), then update the
 * connection's polling based on the channels and stream connector's final
 * states. The function always returns 0.
 */
static int sc_conn_process(struct stconn *sc)
{
	struct connection *conn = __sc_conn(sc);
	struct channel *ic = sc_ic(sc);
	struct channel *oc = sc_oc(sc);

	BUG_ON(!conn);

	/* If we have data to send, try it now */
	if (!channel_is_empty(oc) && !(sc->wait_event.events & SUB_RETRY_SEND))
		sc_conn_send(sc);

	/* First step, report to the stream connector what was detected at the
	 * connection layer : errors and connection establishment.
	 * Only add SE_FL_ERROR if we're connected, or we're attempting to
	 * connect, we may get there because we got woken up, but only run
	 * after process_stream() noticed there were an error, and decided
	 * to retry to connect, the connection may still have CO_FL_ERROR,
	 * and we don't want to add SE_FL_ERROR back
	 *
	 * Note: This test is only required because sc_conn_process is also the SI
	 *       wake callback. Otherwise sc_conn_recv()/sc_conn_send() already take
	 *       care of it.
	 */

	if (sc->state >= SC_ST_CON) {
		if (sc_is_conn_error(sc))
			sc_ep_set(sc, SE_FL_ERROR);
	}

	/* If we had early data, and the handshake ended, then
	 * we can remove the flag, and attempt to wake the task up,
	 * in the event there's an analyser waiting for the end of
	 * the handshake.
	 */
	if (!(conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS)) &&
	    sc_ep_test(sc, SE_FL_WAIT_FOR_HS)) {
		sc_ep_clr(sc, SE_FL_WAIT_FOR_HS);
		task_wakeup(sc_strm_task(sc), TASK_WOKEN_MSG);
	}

	if (!sc_state_in(sc->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO) &&
	    (conn->flags & CO_FL_WAIT_XPRT) == 0) {
		if (sc->flags & SC_FL_ISBACK)
			__sc_strm(sc)->conn_exp = TICK_ETERNITY;
		oc->flags |= CF_WRITE_NULL;
		if (sc->state == SC_ST_CON)
			sc->state = SC_ST_RDY;
	}

	/* Report EOS on the channel if it was reached from the mux point of
	 * view.
	 *
	 * Note: This test is only required because sc_conn_process is also the SI
	 *       wake callback. Otherwise sc_conn_recv()/sc_conn_send() already take
	 *       care of it.
	 */
	if (sc_ep_test(sc, SE_FL_EOS) && !(ic->flags & CF_SHUTR)) {
		/* we received a shutdown */
		ic->flags |= CF_READ_NULL;
		if (ic->flags & CF_AUTO_CLOSE)
			channel_shutw_now(ic);
		sc_conn_read0(sc);
	}

	/* Report EOI on the channel if it was reached from the mux point of
	 * view.
	 *
	 * Note: This test is only required because sc_conn_process is also the SI
	 *       wake callback. Otherwise sc_conn_recv()/sc_conn_send() already take
	 *       care of it.
	 */
	if (sc_ep_test(sc, SE_FL_EOI) && !(ic->flags & CF_EOI))
		ic->flags |= (CF_EOI|CF_READ_PARTIAL);

	/* Second step : update the stream connector and channels, try to forward any
	 * pending data, then possibly wake the stream up based on the new
	 * stream connector status.
	 */
	sc_notify(sc);
	stream_release_buffers(__sc_strm(sc));
	return 0;
}

/* This is the ->process() function for any stream connector's wait_event task.
 * It's assigned during the stream connector's initialization, for any type of
 * stream connector. Thus it is always safe to perform a tasklet_wakeup() on a
 * stream connector, as the presence of the SC is checked there.
 */
struct task *sc_conn_io_cb(struct task *t, void *ctx, unsigned int state)
{
	struct stconn *sc = ctx;
	int ret = 0;

	if (!sc_conn(sc))
		return t;

	if (!(sc->wait_event.events & SUB_RETRY_SEND) && !channel_is_empty(sc_oc(sc)))
		ret = sc_conn_send(sc);
	if (!(sc->wait_event.events & SUB_RETRY_RECV))
		ret |= sc_conn_recv(sc);
	if (ret != 0)
		sc_conn_process(sc);

	stream_release_buffers(__sc_strm(sc));
	return t;
}

/* Callback to be used by applet handlers upon completion. It updates the stream
 * (which may or may not take this opportunity to try to forward data), then
 * may re-enable the applet's based on the channels and stream connector's final
 * states.
 */
static int sc_applet_process(struct stconn *sc)
{
	struct channel *ic = sc_ic(sc);

	BUG_ON(!sc_appctx(sc));

	/* If the applet wants to write and the channel is closed, it's a
	 * broken pipe and it must be reported.
	 */
	if (!sc_ep_test(sc, SE_FL_HAVE_NO_DATA) && (ic->flags & CF_SHUTR))
		sc_ep_set(sc, SE_FL_ERROR);

	/* automatically mark the applet having data available if it reported
	 * begin blocked by the channel.
	 */
	if ((sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM)) ||
	    sc_ep_test(sc, SE_FL_APPLET_NEED_CONN))
		applet_have_more_data(__sc_appctx(sc));

	/* update the stream connector, channels, and possibly wake the stream up */
	sc_notify(sc);
	stream_release_buffers(__sc_strm(sc));

	/* sc_notify may have passed through chk_snd and released some blocking
	 * flags. Process_stream will consider those flags to wake up the
	 * appctx but in the case the task is not in runqueue we may have to
	 * wakeup the appctx immediately.
	 */
	if (sc_is_recv_allowed(sc) || sc_is_send_allowed(sc))
		appctx_wakeup(__sc_appctx(sc));
	return 0;
}


/* Prepares an endpoint upgrade. We don't now at this stage if the upgrade will
 * succeed or not and if the stconn will be reused by the new endpoint. Thus,
 * for now, only pretend the stconn is detached.
 */
void sc_conn_prepare_endp_upgrade(struct stconn *sc)
{
	BUG_ON(!sc_conn(sc) || !sc->app);
	sc_ep_clr(sc, SE_FL_T_MUX);
	sc_ep_set(sc, SE_FL_DETACHED);
}

/* Endpoint upgrade failed. Restore the stconn state. */
void sc_conn_abort_endp_upgrade(struct stconn *sc)
{
	sc_ep_set(sc, SE_FL_T_MUX);
	sc_ep_clr(sc, SE_FL_DETACHED);
}

/* Commit the endpoint upgrade. If stconn is attached, it means the new endpoint
 * use it. So we do nothing. Otherwise, the stconn will be destroy with the
 * overlying stream. So, it means we must commit the detach.
*/
void sc_conn_commit_endp_upgrade(struct stconn *sc)
{
	if (!sc_ep_test(sc, SE_FL_DETACHED))
		return;
	sc_detach_endp(&sc);
	/* Because it was already set as detached, the sedesc must be preserved */
	BUG_ON(!sc);
	BUG_ON(!sc->sedesc);
}
