From cff6d757e3ba609c08ef2aaa00f07e53551e5bf6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 3 Jun 2024 07:11:10 +0200 Subject: Adding upstream version 3.0.0. Signed-off-by: Daniel Baumann --- src/quic_fctl.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/quic_fctl.c (limited to 'src/quic_fctl.c') diff --git a/src/quic_fctl.c b/src/quic_fctl.c new file mode 100644 index 0000000..b797e55 --- /dev/null +++ b/src/quic_fctl.c @@ -0,0 +1,96 @@ +#include + +#include + +void qfctl_init(struct quic_fctl *fctl, uint64_t limit) +{ + fctl->limit = limit; + fctl->off_real = 0; + fctl->off_soft = 0; +} + +/* Returns true if real limit is blocked for flow control instance. + * This happens if it is equal than current max value. + */ +int qfctl_rblocked(const struct quic_fctl *fctl) +{ + /* Real limit must never be exceeded. */ + BUG_ON(fctl->off_real > fctl->limit); + return fctl->off_real == fctl->limit; +} + +/* Returns true if soft limit is blocked for flow control instance. + * This happens if it is equal or greater than current max value. + */ +int qfctl_sblocked(const struct quic_fctl *fctl) +{ + return fctl->off_soft >= fctl->limit; +} + +/* Set a new maximum value for flow control instance. If current + * offset is already equal or more, the new value is ignored. Additionally, + * and can be used as output parameters to + * detect if the current update result in one or both of these offsets to be + * unblocked. + * + * Returns true if max is incremented else false. + */ +int qfctl_set_max(struct quic_fctl *fctl, uint64_t val, + int *out_unblock_soft, int *out_unblock_real) +{ + int unblock_soft = 0, unblock_real = 0; + int ret = 0; + + if (fctl->limit < val) { + if (fctl->off_soft >= fctl->limit && fctl->off_soft < val) + unblock_soft = 1; + if (fctl->off_real == fctl->limit && fctl->off_real < val) + unblock_real = 1; + + fctl->limit = val; + ret = 1; + } + + if (out_unblock_soft) + *out_unblock_soft = unblock_soft; + if (out_unblock_real) + *out_unblock_real = unblock_real; + + return ret; +} + +/* Increment real offset of flow control instance by . This cannot + * exceed limit. + * + * Returns true if limit is reached after increment. + */ +int qfctl_rinc(struct quic_fctl *fctl, uint64_t diff) +{ + /* Real limit must never be exceeded. */ + BUG_ON(fctl->off_real + diff > fctl->limit); + fctl->off_real += diff; + + return fctl->off_real == fctl->limit; +} + +/* Increment soft offset of flow control instance by . This cannot + * be done if limit was already reached. + * + * Returns true if limit is reached after increment. + */ +int qfctl_sinc(struct quic_fctl *fctl, uint64_t diff) +{ + /* Soft limit must not be incremented if already in excess. */ + BUG_ON(qfctl_sblocked(fctl)); + fctl->off_soft += diff; + + return fctl->off_soft >= fctl->limit; +} + +/* Return the remaining offset before reaching limit. */ +uint64_t qfctl_rcap(const struct quic_fctl *fctl) +{ + /* Real limit must never be exceeded. */ + BUG_ON(fctl->off_real > fctl->limit); + return fctl->limit - fctl->off_real; +} -- cgit v1.2.3