/*
 * HTTP/3 protocol processing
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, version 2.1
 * exclusively.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <haproxy/buf.h>
#include <haproxy/connection.h>
#include <haproxy/conn_stream.h>
#include <haproxy/dynbuf.h>
#include <haproxy/h3.h>
#include <haproxy/http.h>
#include <haproxy/htx.h>
#include <haproxy/istbuf.h>
#include <haproxy/mux_quic-t.h>
#include <haproxy/pool.h>
#include <haproxy/qpack-dec.h>
#include <haproxy/qpack-enc.h>
#include <haproxy/quic_enc.h>
#include <haproxy/stream.h>
#include <haproxy/tools.h>
#include <haproxy/xprt_quic.h>

#if defined(DEBUG_H3)
#define h3_debug_printf fprintf
#define h3_debug_hexdump debug_hexdump
#else
#define h3_debug_printf(...) do { } while (0)
#define h3_debug_hexdump(...) do { } while (0)
#endif

#define H3_CF_SETTINGS_SENT  0x00000001

/* Default settings */
static uint64_t h3_settings_qpack_max_table_capacity = 0;
static uint64_t h3_settings_qpack_blocked_streams = 4096;
static uint64_t h3_settings_max_field_section_size = QUIC_VARINT_8_BYTE_MAX; /* Unlimited */

struct h3 {
	struct qcc *qcc;
	enum h3_err err;
	uint32_t flags;
	/* Locally initiated uni-streams */
	struct h3_uqs lqpack_enc;
	struct h3_uqs lqpack_dec;
	struct h3_uqs lctrl;
	/* Remotely initiated uni-streams */
	struct h3_uqs rqpack_enc;
	struct h3_uqs rqpack_dec;
	struct h3_uqs rctrl;
	/* Settings */
	uint64_t qpack_max_table_capacity;
	uint64_t qpack_blocked_streams;
	uint64_t max_field_section_size;
	struct buffer_wait buf_wait; /* wait list for buffer allocations */
};

DECLARE_STATIC_POOL(pool_head_h3, "h3", sizeof(struct h3));

/* Simple function to duplicate a buffer */
static inline struct buffer h3_b_dup(struct buffer *b)
{
	return b_make(b->area, b->size, b->head, b->data);
}

/* Decode a h3 frame header made of two QUIC varints from <b> buffer.
 * Returns the number of bytes consumed if there was enough data in <b>, 0 if not.
 * Note that this function update <b> buffer to reflect the number of bytes consumed
 * to decode the h3 frame header.
 */
static inline size_t h3_decode_frm_header(uint64_t *ftype, uint64_t *flen,
                                          struct buffer *b)
{
	size_t hlen;

	hlen = 0;
	if (!b_quic_dec_int(ftype, b, &hlen) || !b_quic_dec_int(flen, b, &hlen))
		return 0;

	return hlen;
}

/* Parse from buffer <buf> a H3 HEADERS frame of length <len>. Data are copied
 * in a local HTX buffer and transfer to the conn-stream layer. <fin> must be
 * set if this is the last data to transfer from this stream.
 *
 * Returns 0 on success else non-zero.
 */
static int h3_headers_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len,
                             char fin)
{
	struct buffer htx_buf = BUF_NULL;
	struct buffer *tmp = get_trash_chunk();
	struct htx *htx = NULL;
	struct htx_sl *sl;
	struct http_hdr list[global.tune.max_http_hdr];
	struct conn_stream *cs;
	unsigned int flags = HTX_SL_F_NONE;
	struct ist meth = IST_NULL, path = IST_NULL;
	//struct ist scheme = IST_NULL, authority = IST_NULL;
	struct ist authority = IST_NULL;
	int hdr_idx;

	if (qpack_decode_fs((const unsigned char *)b_head(buf), len, tmp, list) < 0)
		return 1;

	qc_get_buf(qcs, &htx_buf);
	BUG_ON(!b_size(&htx_buf));
	htx = htx_from_buf(&htx_buf);

	/* first treat pseudo-header to build the start line */
	hdr_idx = 0;
	while (1) {
		if (isteq(list[hdr_idx].n, ist("")))
			break;

		if (istmatch(list[hdr_idx].n, ist(":"))) {
			/* pseudo-header */
			if (isteq(list[hdr_idx].n, ist(":method")))
				meth = list[hdr_idx].v;
			else if (isteq(list[hdr_idx].n, ist(":path")))
				path = list[hdr_idx].v;
			//else if (isteq(list[hdr_idx].n, ist(":scheme")))
			//	scheme = list[hdr_idx].v;
			else if (isteq(list[hdr_idx].n, ist(":authority")))
				authority = list[hdr_idx].v;
		}

		++hdr_idx;
	}

	flags |= HTX_SL_F_VER_11;

	sl = htx_add_stline(htx, HTX_BLK_REQ_SL, flags, meth, path, ist("HTTP/3.0"));
	if (!sl)
		return 1;

	if (fin)
		sl->flags |= HTX_SL_F_BODYLESS;

	sl->info.req.meth = find_http_meth(meth.ptr, meth.len);
	BUG_ON(sl->info.req.meth == HTTP_METH_OTHER);

	if (isttest(authority))
		htx_add_header(htx, ist("host"), authority);

	/* now treat standard headers */
	hdr_idx = 0;
	while (1) {
		if (isteq(list[hdr_idx].n, ist("")))
			break;

		if (!istmatch(list[hdr_idx].n, ist(":")))
			htx_add_header(htx, list[hdr_idx].n, list[hdr_idx].v);

		++hdr_idx;
	}

	htx_add_endof(htx, HTX_BLK_EOH);
	htx_to_buf(htx, &htx_buf);

	if (fin)
		htx->flags |= HTX_FL_EOM;

	cs = cs_new();
	if (!cs)
		return 1;
	cs_attach_endp(cs, &qcs->qcc->conn->obj_type, qcs);

	cs->flags |= CS_FL_NOT_FIRST;
	cs->ctx = qcs;
	stream_new(qcs->qcc->conn->owner, cs, &htx_buf);

	/* buffer is transferred to conn_stream and set to NULL
	 * except on stream creation error.
	 */
	b_free(&htx_buf);
	offer_buffers(NULL, 1);

	return 0;
}

/* Copy from buffer <buf> a H3 DATA frame of length <len> in QUIC stream <qcs>
 * HTX buffer. <fin> must be set if this is the last data to transfer from this
 * stream.
 *
 * Returns 0 on success else non-zero
 */
static int h3_data_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len,
                          char fin)
{
	struct buffer *appbuf;
	struct htx *htx = NULL;
	size_t htx_sent;
	int htx_space;

	appbuf = qc_get_buf(qcs, &qcs->rx.app_buf);
	BUG_ON(!appbuf);
	htx = htx_from_buf(appbuf);

	htx_space = htx_free_data_space(htx);
	if (!htx_space || htx_space < len) {
		ABORT_NOW(); /* TODO handle this case properly */
	}

	htx_sent = htx_add_data(htx, ist2(b_head(buf), len));
	if (htx_sent < len) {
		ABORT_NOW(); /* TODO handle this case properly */
	}

	if (fin)
		htx->flags |= HTX_FL_EOM;
	htx_to_buf(htx, appbuf);

	return 0;
}

/* Decode <qcs> remotely initiated bidi-stream. <fin> must be set to indicate
 * that we received the last data of the stream.
 * Returns <0 on error else 0.
 */
static int h3_decode_qcs(struct qcs *qcs, int fin, void *ctx)
{
	struct buffer *rxbuf = &qcs->rx.buf;
	int ret;

	h3_debug_printf(stderr, "%s: STREAM ID: %llu\n", __func__, qcs->by_id.key);
	if (!b_data(rxbuf))
		return 0;

	while (b_data(rxbuf)) {
		size_t hlen;
		uint64_t ftype, flen;
		struct buffer b;
		char last_stream_frame = 0;

		/* Work on a copy of <rxbuf> */
		b = h3_b_dup(rxbuf);
		hlen = h3_decode_frm_header(&ftype, &flen, &b);
		if (!hlen)
			break;

		h3_debug_printf(stderr, "%s: ftype: %llu, flen: %llu\n", __func__,
		        (unsigned long long)ftype, (unsigned long long)flen);
		if (flen > b_data(&b) && !b_full(rxbuf))
			break;

		/* TODO handle full rxbuf */
		BUG_ON(flen > b_size(rxbuf));

		b_del(rxbuf, hlen);
		last_stream_frame = (fin && flen == b_data(rxbuf));

		switch (ftype) {
		case H3_FT_DATA:
			ret = h3_data_to_htx(qcs, rxbuf, flen, last_stream_frame);
			/* TODO handle error reporting. Stream closure required. */
			if (ret) { ABORT_NOW(); }
			break;
		case H3_FT_HEADERS:
			ret = h3_headers_to_htx(qcs, rxbuf, flen, last_stream_frame);
			/* TODO handle error reporting. Stream closure required. */
			if (ret) { ABORT_NOW(); }
			break;
		case H3_FT_PUSH_PROMISE:
			/* Not supported */
			break;
		default:
			/* draft-ietf-quic-http34 9. Extensions to HTTP/3
			 * unknown frame types MUST be ignored
			 */
			h3_debug_printf(stderr, "ignore unknown frame type 0x%lx\n", ftype);
		}
		b_del(rxbuf, flen);
	}

	return 0;
}

/* Parse a SETTINGS frame which must not be truncated with <flen> as length from
 * <rxbuf> buffer. This function does not update this buffer.
 * Returns 0 if something wrong happened, 1 if not.
 */
static int h3_parse_settings_frm(struct h3 *h3, const struct buffer *rxbuf, size_t flen)
{
	uint64_t id, value;
	const unsigned char *buf, *end;

	buf = (const unsigned char *)b_head(rxbuf);
	end = buf + flen;

	while (buf <= end) {
		if (!quic_dec_int(&id, &buf, end) || !quic_dec_int(&value, &buf, end))
			return 0;

		h3_debug_printf(stderr, "%s id: %llu value: %llu\n",
		                __func__, (unsigned long long)id, (unsigned long long)value);
		switch (id) {
		case H3_SETTINGS_QPACK_MAX_TABLE_CAPACITY:
			h3->qpack_max_table_capacity = value;
			break;
		case H3_SETTINGS_MAX_FIELD_SECTION_SIZE:
			h3->max_field_section_size = value;
			break;
		case H3_SETTINGS_QPACK_BLOCKED_STREAMS:
			h3->qpack_blocked_streams = value;
			break;
		case H3_SETTINGS_RESERVED_2 ... H3_SETTINGS_RESERVED_5:
			h3->err = H3_SETTINGS_ERROR;
			return 0;
		default:
			/* MUST be ignored */
			break;
		}
	}

	return 1;
}

/* Decode <qcs> remotely initiated uni-stream. We stop parsing a frame as soon as
 * there is not enough received data.
 * Returns 0 if something wrong happened, 1 if not.
 */
static int h3_control_recv(struct h3_uqs *h3_uqs, void *ctx)
{
	struct buffer *rxbuf = &h3_uqs->qcs->rx.buf;
	struct h3 *h3 = ctx;

	h3_debug_printf(stderr, "%s STREAM ID: %llu\n", __func__,  h3_uqs->qcs->by_id.key);
	if (!b_data(rxbuf))
		return 1;

	while (b_data(rxbuf)) {
		size_t hlen;
		uint64_t ftype, flen;
		struct buffer b;

		/* Work on a copy of <rxbuf> */
		b = h3_b_dup(rxbuf);
		hlen = h3_decode_frm_header(&ftype, &flen, &b);
		if (!hlen)
			break;

		h3_debug_printf(stderr, "%s: ftype: %llu, flen: %llu\n", __func__,
		        (unsigned long long)ftype, (unsigned long long)flen);
		if (flen > b_data(&b))
			break;

		b_del(rxbuf, hlen);
		/* From here, a frame must not be truncated */
		switch (ftype) {
		case H3_FT_CANCEL_PUSH:
			/* XXX TODO XXX */
			ABORT_NOW();
			break;
		case H3_FT_SETTINGS:
			if (!h3_parse_settings_frm(h3, rxbuf, flen))
				return 0;
			break;
		case H3_FT_GOAWAY:
			/* XXX TODO XXX */
			ABORT_NOW();
			break;
		case H3_FT_MAX_PUSH_ID:
			/* XXX TODO XXX */
			ABORT_NOW();
			break;
		default:
			/* Error */
			h3->err = H3_FRAME_UNEXPECTED;
			return 0;
		}
		b_del(rxbuf, flen);
	}

	/* Handle the case where remaining data are present in the buffer. This
	 * can happen if there is an incomplete frame. In this case, subscribe
	 * on the lower layer to restart receive operation.
	 */
	if (b_data(rxbuf))
		qcs_subscribe(h3_uqs->qcs, SUB_RETRY_RECV, &h3_uqs->wait_event);

	return 1;
}

/* Returns buffer for data sending.
 * May be NULL if the allocation failed.
 */
static struct buffer *mux_get_buf(struct qcs *qcs)
{
	if (!b_size(&qcs->tx.buf))
		b_alloc(&qcs->tx.buf);

	return &qcs->tx.buf;
}

/* Function used to emit stream data from <h3_uqs> control uni-stream */
static int h3_control_send(struct h3_uqs *h3_uqs, void *ctx)
{
	int ret;
	struct h3 *h3 = ctx;
	unsigned char data[(2 + 3) * 2 * QUIC_VARINT_MAX_SIZE]; /* enough for 3 settings */
	struct buffer pos, *res;

	ret = 0;
	pos = b_make((char *)data, sizeof(data), 0, 0);
	if (!(h3->flags & H3_CF_SETTINGS_SENT)) {
		struct qcs *qcs = h3_uqs->qcs;
		size_t frm_len;

		frm_len = quic_int_getsize(H3_SETTINGS_QPACK_MAX_TABLE_CAPACITY) +
			quic_int_getsize(h3_settings_qpack_max_table_capacity) +
			quic_int_getsize(H3_SETTINGS_QPACK_BLOCKED_STREAMS) +
			quic_int_getsize(h3_settings_qpack_blocked_streams);
		if (h3_settings_max_field_section_size) {
			frm_len += quic_int_getsize(H3_SETTINGS_MAX_FIELD_SECTION_SIZE) +
			quic_int_getsize(h3_settings_max_field_section_size);
		}

		b_quic_enc_int(&pos, H3_UNI_STRM_TP_CONTROL_STREAM);
		/* Build a SETTINGS frame */
		b_quic_enc_int(&pos, H3_FT_SETTINGS);
		b_quic_enc_int(&pos, frm_len);
		b_quic_enc_int(&pos, H3_SETTINGS_QPACK_MAX_TABLE_CAPACITY);
		b_quic_enc_int(&pos, h3_settings_qpack_max_table_capacity);
		b_quic_enc_int(&pos, H3_SETTINGS_QPACK_BLOCKED_STREAMS);
		b_quic_enc_int(&pos, h3_settings_qpack_blocked_streams);
		if (h3_settings_max_field_section_size) {
			b_quic_enc_int(&pos, H3_SETTINGS_MAX_FIELD_SECTION_SIZE);
			b_quic_enc_int(&pos, h3_settings_max_field_section_size);
		}

		res = mux_get_buf(qcs);
		if (b_room(res) < b_data(&pos)) {
			// TODO the mux should be put in blocked state, with
			// the stream in state waiting for settings to be sent
			ABORT_NOW();
		}

		ret = b_force_xfer(res, &pos, b_data(&pos));
		if (ret > 0) {
			h3->flags |= H3_CF_SETTINGS_SENT;
			if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND))
				tasklet_wakeup(qcs->qcc->wait_event.tasklet);
		}
	}

	return ret;
}

static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx)
{
	struct buffer outbuf;
	struct buffer headers_buf = BUF_NULL;
	struct buffer *res;
	struct http_hdr list[global.tune.max_http_hdr];
	struct htx_sl *sl;
	struct htx_blk *blk;
	enum htx_blk_type type;
	int frame_length_size;  /* size in bytes of frame length varint field */
	int ret = 0;
	int hdr;
	int status = 0;

	sl = NULL;
	hdr = 0;
	for (blk = htx_get_head_blk(htx); blk; blk = htx_get_next_blk(htx, blk)) {
		type = htx_get_blk_type(blk);

		if (type == HTX_BLK_UNUSED)
			continue;

		if (type == HTX_BLK_EOH)
			break;

		if (type == HTX_BLK_RES_SL) {
			/* start-line -> HEADERS h3 frame */
			BUG_ON(sl);
			sl = htx_get_blk_ptr(htx, blk);
			/* TODO should be on h3 layer */
			status = sl->info.res.status;
		}
		else if (type == HTX_BLK_HDR) {
			list[hdr].n = htx_get_blk_name(htx, blk);
			list[hdr].v = htx_get_blk_value(htx, blk);
			hdr++;
		}
		else {
			ABORT_NOW();
			goto err;
		}
	}

	BUG_ON(!sl);

	list[hdr].n = ist("");

	res = mux_get_buf(qcs);

	/* At least 5 bytes to store frame type + length as a varint max size */
	if (b_room(res) < 5)
		ABORT_NOW();

	b_reset(&outbuf);
	outbuf = b_make(b_tail(res), b_contig_space(res), 0, 0);
	/* Start the headers after frame type + length */
	headers_buf = b_make(b_head(res) + 5, b_size(res) - 5, 0, 0);

	if (qpack_encode_field_section_line(&headers_buf))
		ABORT_NOW();
	if (qpack_encode_int_status(&headers_buf, status))
		ABORT_NOW();

	for (hdr = 0; hdr < sizeof(list) / sizeof(list[0]); ++hdr) {
		if (isteq(list[hdr].n, ist("")))
			break;

		/* draft-ietf-quic-http34 4.1. HTTP Message Exchanges
		 * Transfer codings (see Section 6.1 of [HTTP11]) are not
		 * defined for HTTP/3; the Transfer-Encoding header field MUST
		 * NOT be used.
		 */
		if (isteq(list[hdr].n, ist("transfer-encoding")))
			continue;

		if (qpack_encode_header(&headers_buf, list[hdr].n, list[hdr].v))
			ABORT_NOW();
	}

	/* Now that all headers are encoded, we are certain that res buffer is
	 * big enough
	 */
	frame_length_size = quic_int_getsize(b_data(&headers_buf));
	res->head += 4 - frame_length_size;
	b_putchr(res, 0x01); /* h3 HEADERS frame type */
	if (!b_quic_enc_int(res, b_data(&headers_buf)))
		ABORT_NOW();
	b_add(res, b_data(&headers_buf));

	ret = 0;
	blk = htx_get_head_blk(htx);
	while (blk) {
		type = htx_get_blk_type(blk);
		ret += htx_get_blksz(blk);
		blk = htx_remove_blk(htx, blk);
		if (type == HTX_BLK_EOH)
			break;
	}

	return ret;

 err:
	return 0;
}

/* Returns the total of bytes sent. */
static int h3_resp_data_send(struct qcs *qcs, struct buffer *buf, size_t count)
{
	struct buffer outbuf;
	struct buffer *res;
	size_t total = 0;
	struct htx *htx;
	int bsize, fsize, hsize;
	struct htx_blk *blk;
	enum htx_blk_type type;

	htx = htx_from_buf(buf);

 new_frame:
	if (!count || htx_is_empty(htx))
		goto end;

	blk = htx_get_head_blk(htx);
	type = htx_get_blk_type(blk);
	fsize = bsize = htx_get_blksz(blk);

	if (type != HTX_BLK_DATA)
		goto end;

	res = mux_get_buf(qcs);

	if (fsize > count)
		fsize = count;

	/* h3 DATA headers : 1-byte frame type + varint frame length */
	hsize = 1 + QUIC_VARINT_MAX_SIZE;

	while (1) {
		b_reset(&outbuf);
		outbuf = b_make(b_tail(res), b_contig_space(res), 0, 0);
		if (b_size(&outbuf) > hsize || !b_space_wraps(res))
			break;
		b_slow_realign(res, trash.area, b_data(res));
	}

	/* Not enough room for headers and at least one data byte, block the
	 * stream. It is expected that the conn-stream layer will subscribe on
	 * SEND.
	 */
	if (b_size(&outbuf) <= hsize) {
		qcs->flags |= QC_SF_BLK_MROOM;
		goto end;
	}

	if (b_size(&outbuf) < hsize + fsize)
		fsize = b_size(&outbuf) - hsize;
	BUG_ON(fsize <= 0);

	b_putchr(&outbuf, 0x00);        /* h3 frame type = DATA */
	b_quic_enc_int(&outbuf, fsize); /* h3 frame length */

	b_putblk(&outbuf, htx_get_blk_ptr(htx, blk), fsize);
	total += fsize;
	count -= fsize;

	if (fsize == bsize)
		htx_remove_blk(htx, blk);
	else
		htx_cut_data_blk(htx, blk, fsize);

	/* commit the buffer */
	b_add(res, b_data(&outbuf));
	goto new_frame;

 end:
	return total;
}

size_t h3_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
{
	size_t total = 0;
	struct qcs *qcs = cs->ctx;
	struct htx *htx;
	enum htx_blk_type btype;
	struct htx_blk *blk;
	uint32_t bsize;
	int32_t idx;
	int ret;

	h3_debug_printf(stderr, "%s\n", __func__);

	htx = htx_from_buf(buf);

	while (count && !htx_is_empty(htx) && !(qcs->flags & QC_SF_BLK_MROOM)) {
		idx = htx_get_head(htx);
		blk = htx_get_blk(htx, idx);
		btype = htx_get_blk_type(blk);
		bsize = htx_get_blksz(blk);

		/* Not implemented : QUIC on backend side */
		BUG_ON(btype == HTX_BLK_REQ_SL);

		switch (btype) {
		case HTX_BLK_RES_SL:
			/* start-line -> HEADERS h3 frame */
			ret = h3_resp_headers_send(qcs, htx);
			if (ret > 0) {
				total += ret;
				count -= ret;
				if (ret < bsize)
					goto out;
			}
			break;

		case HTX_BLK_DATA:
			ret = h3_resp_data_send(qcs, buf, count);
			if (ret > 0) {
				htx = htx_from_buf(buf);
				total += ret;
				count -= ret;
				if (ret < bsize)
					goto out;
			}
			break;

		case HTX_BLK_TLR:
		case HTX_BLK_EOT:
			/* TODO trailers */

		default:
			htx_remove_blk(htx, blk);
			total += bsize;
			count -= bsize;
			break;
		}
	}

	if ((htx->flags & HTX_FL_EOM) && htx_is_empty(htx))
		qcs->flags |= QC_SF_FIN_STREAM;

 out:
	if (total) {
		if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND))
			tasklet_wakeup(qcs->qcc->wait_event.tasklet);
	}

	return total;
}

/* Finalize the initialization of remotely initiated uni-stream <qcs>.
 * Return 1 if succeeded, 0 if not. In this latter case, set the ->err h3 error
 * to inform the QUIC mux layer of the encountered error.
 */
static int h3_attach_ruqs(struct qcs *qcs, void *ctx)
{
	uint64_t strm_type;
	struct h3 *h3 = ctx;
	struct buffer *rxbuf = &qcs->rx.buf;

	/* First octets: the uni-stream type */
	if (!b_quic_dec_int(&strm_type, rxbuf, NULL) || strm_type > H3_UNI_STRM_TP_MAX)
		return 0;

	/* Note that for all the uni-streams below, this is an error to receive two times the
	 * same type of uni-stream (even for Push stream which is not supported at this time.
	 */
	switch (strm_type) {
	case H3_UNI_STRM_TP_CONTROL_STREAM:
		if (h3->rctrl.qcs) {
			h3->err = H3_STREAM_CREATION_ERROR;
			return 0;
		}

		h3->rctrl.qcs = qcs;
		h3->rctrl.cb = h3_control_recv;
		qcs_subscribe(qcs, SUB_RETRY_RECV, &h3->rctrl.wait_event);
		break;
	case H3_UNI_STRM_TP_PUSH_STREAM:
		/* NOT SUPPORTED */
		break;
	case H3_UNI_STRM_TP_QPACK_ENCODER:
		if (h3->rqpack_enc.qcs) {
			h3->err = H3_STREAM_CREATION_ERROR;
			return 0;
		}

		h3->rqpack_enc.qcs = qcs;
		h3->rqpack_enc.cb = qpack_decode_enc;
		qcs_subscribe(qcs, SUB_RETRY_RECV, &h3->rqpack_enc.wait_event);
		break;
	case H3_UNI_STRM_TP_QPACK_DECODER:
		if (h3->rqpack_dec.qcs) {
			h3->err = H3_STREAM_CREATION_ERROR;
			return 0;
		}

		h3->rqpack_dec.qcs = qcs;
		h3->rqpack_dec.cb = qpack_decode_dec;
		qcs_subscribe(qcs, SUB_RETRY_RECV, &h3->rqpack_dec.wait_event);
		break;
	default:
		/* Error */
		h3->err = H3_STREAM_CREATION_ERROR;
		return 0;
	}

	return 1;
}

static int h3_finalize(void *ctx)
{
	struct h3 *h3 = ctx;

	h3->lctrl.qcs = qcs_new(h3->qcc, 0x3, QCS_SRV_UNI);
	if (!h3->lctrl.qcs)
		return 0;

	/* Wakeup ->lctrl uni-stream */
	h3_control_send(&h3->lctrl, h3);

	return 1;
}

/* Tasklet dedicated to h3 incoming uni-streams */
static struct task *h3_uqs_task(struct task *t, void *ctx, unsigned int state)
{
	struct h3_uqs *h3_uqs = ctx;
	struct h3 *h3 = h3_uqs->qcs->qcc->ctx;

	h3_uqs->cb(h3_uqs, h3);
	return NULL;
}

/* Release all the tasklet attached to <h3_uqs> uni-stream */
static inline void h3_uqs_tasklet_release(struct h3_uqs *h3_uqs)
{
	struct tasklet *t = h3_uqs->wait_event.tasklet;

	if (t)
		tasklet_free(t);
}

/* Release all the tasklet attached to <h3> uni-streams */
static void h3_uqs_tasklets_release(struct h3 *h3)
{
	h3_uqs_tasklet_release(&h3->rqpack_enc);
	h3_uqs_tasklet_release(&h3->rqpack_dec);
	h3_uqs_tasklet_release(&h3->rctrl);
}

/* Tasklet dedicated to h3 outgoing uni-streams */
__maybe_unused
static struct task *h3_uqs_send_task(struct task *t, void *ctx, unsigned int state)
{
	struct h3_uqs *h3_uqs = ctx;
	struct h3 *h3 = h3_uqs->qcs->qcc->ctx;

	h3_uqs->cb(h3_uqs, h3);
	return NULL;
}

/* Initialize <h3_uqs> uni-stream with <t> as tasklet */
static int h3_uqs_init(struct h3_uqs *h3_uqs, struct h3 *h3,
                       int (*cb)(struct h3_uqs *h3_uqs, void *ctx),
                       struct task *(*t)(struct task *, void *, unsigned int))
{
	h3_uqs->qcs = NULL;
	h3_uqs->cb = cb;
	h3_uqs->wait_event.tasklet = tasklet_new();
	if (!h3_uqs->wait_event.tasklet)
		return 0;

	h3_uqs->wait_event.tasklet->process = t;
	h3_uqs->wait_event.tasklet->context = h3_uqs;
	h3_uqs->wait_event.events = 0;
	return 1;
}

static inline void h3_uqs_release(struct h3_uqs *h3_uqs)
{
	if (h3_uqs->qcs)
		qcs_free(h3_uqs->qcs);
}

static inline void h3_uqs_release_all(struct h3 *h3)
{
	h3_uqs_tasklet_release(&h3->lctrl);
	h3_uqs_release(&h3->lctrl);
	h3_uqs_tasklet_release(&h3->lqpack_enc);
	h3_uqs_release(&h3->lqpack_enc);
	h3_uqs_tasklet_release(&h3->lqpack_dec);
	h3_uqs_release(&h3->lqpack_dec);
}

/* Initialize the HTTP/3 context for <qcc> mux.
 * Return 1 if succeeded, 0 if not.
 */
static int h3_init(struct qcc *qcc)
{
	struct h3 *h3;

	h3 = pool_alloc(pool_head_h3);
	if (!h3)
		goto fail_no_h3;

	h3->qcc = qcc;
	h3->err = H3_NO_ERROR;
	h3->flags = 0;

	if (!h3_uqs_init(&h3->rqpack_enc, h3, NULL, h3_uqs_task) ||
	    !h3_uqs_init(&h3->rqpack_dec, h3, NULL, h3_uqs_task) ||
	    !h3_uqs_init(&h3->rctrl, h3, h3_control_recv, h3_uqs_task))
		goto fail_no_h3_ruqs;

	if (!h3_uqs_init(&h3->lctrl, h3, h3_control_send, h3_uqs_task) ||
	    !h3_uqs_init(&h3->lqpack_enc, h3, NULL, h3_uqs_task) ||
	    !h3_uqs_init(&h3->lqpack_dec, h3, NULL, h3_uqs_task))
		goto fail_no_h3_luqs;

	qcc->ctx = h3;
	LIST_INIT(&h3->buf_wait.list);

	return 1;

 fail_no_h3_ruqs:
	h3_uqs_release_all(h3);
 fail_no_h3_luqs:
	h3_uqs_tasklets_release(h3);
	pool_free(pool_head_h3, h3);
 fail_no_h3:
	return 0;
}

static void h3_release(void *ctx)
{
	struct h3 *h3 = ctx;

	h3_uqs_release_all(h3);
	h3_uqs_tasklets_release(h3);
	pool_free(pool_head_h3, h3);
}

/* HTTP/3 application layer operations */
const struct qcc_app_ops h3_ops = {
	.init        = h3_init,
	.attach_ruqs = h3_attach_ruqs,
	.decode_qcs  = h3_decode_qcs,
	.snd_buf     = h3_snd_buf,
	.finalize    = h3_finalize,
	.release     = h3_release,
};
