[6.0] cfba2637e Add vmod_h2 to control rapid_reset parameters per session
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Wed Oct 18 16:40:08 UTC 2023
commit cfba2637e10f3b23db9fa301bb353fb74f207b01
Author: Dag Haavi Finstad <daghf at varnish-software.com>
Date: Wed Oct 18 15:17:27 2023 +0200
Add vmod_h2 to control rapid_reset parameters per session
Backport of 2cfb561ed46a2db1e6c2ef9f88cbb8eebb792f25 and 1a406e3f9a085f9d9321242c94a99080eb2be525
Conflicts:
bin/varnishtest/vmods.h
configure.ac
lib/Makefile.am
diff --git a/bin/varnishtest/vmods.h b/bin/varnishtest/vmods.h
index 06ab9b80c..81c12cbdb 100644
--- a/bin/varnishtest/vmods.h
+++ b/bin/varnishtest/vmods.h
@@ -35,3 +35,4 @@ VTC_VMOD(vtc)
VTC_VMOD(blob)
VTC_VMOD(unix)
VTC_VMOD(proxy)
+VTC_VMOD(h2)
diff --git a/bin/varnishtest/vmodtests/h2/b00000.vtc b/bin/varnishtest/vmodtests/h2/b00000.vtc
new file mode 100644
index 000000000..aedb6aad8
--- /dev/null
+++ b/bin/varnishtest/vmodtests/h2/b00000.vtc
@@ -0,0 +1,90 @@
+varnishtest "VMOD h2 basics"
+
+varnish v1 -arg "-p feature=+http2" -vcl {
+ import h2;
+
+ backend proforma none;
+
+ sub vcl_recv {
+ return(synth(200));
+ }
+
+ sub vcl_synth {
+ set resp.http.http2-is = h2.is();
+ set resp.body = "";
+ return (deliver);
+ }
+} -start
+
+client c1 {
+ txreq
+ rxresp
+ expect resp.status == 200
+ expect resp.http.http2-is == false
+} -start
+
+client c2 {
+ stream 7 {
+ txreq
+ rxresp
+ expect resp.status == 200
+ expect resp.http.http2-is == true
+ } -run
+} -start
+
+client c1 -wait
+client c2 -wait
+
+# coverage
+varnish v1 -vcl {
+ import h2;
+
+ backend proforma none;
+
+ sub vcl_recv {
+ return(synth(200));
+ }
+
+ sub vcl_synth {
+ set resp.http.rapid-reset-o = h2.rapid_reset(10ms);
+ set resp.http.rapid-reset-n = h2.rapid_reset();
+ set resp.http.rapid-reset-limit-o = h2.rapid_reset_limit(10);
+ set resp.http.rapid-reset-limit-n = h2.rapid_reset_limit();
+ set resp.http.rapid-reset-period-o = h2.rapid_reset_period(10s);
+ set resp.http.rapid-reset-period-n = h2.rapid_reset_period();
+ set resp.http.rapid-reset-budget = h2.rapid_reset_budget();
+ set resp.body = "";
+ return (deliver);
+ }
+}
+
+client c1 {
+ txreq
+ rxresp
+ expect resp.status == 200
+ expect resp.http.rapid-reset-o == -1.000
+ expect resp.http.rapid-reset-n == -1.000
+ expect resp.http.rapid-reset-limit-o == -1
+ expect resp.http.rapid-reset-limit-n == -1
+ expect resp.http.rapid-reset-period-o == -1.000
+ expect resp.http.rapid-reset-period-n == -1.000
+ expect resp.http.rapid-reset-budget == -1.000
+} -start
+
+client c2 {
+ stream 7 {
+ txreq
+ rxresp
+ expect resp.status == 200
+ expect resp.http.rapid-reset-o == 1.000
+ expect resp.http.rapid-reset-n == 0.010
+ expect resp.http.rapid-reset-limit-o == 100
+ expect resp.http.rapid-reset-limit-n == 10
+ expect resp.http.rapid-reset-period-o == 60.000
+ expect resp.http.rapid-reset-period-n == 10.000
+ expect resp.http.rapid-reset-budget == 10.000
+ } -run
+} -start
+
+client c1 -wait
+client c2 -wait
diff --git a/configure.ac b/configure.ac
index b5e8b45ab..d7c7c33ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -784,6 +784,7 @@ AC_CONFIG_FILES([
lib/libvmod_blob/Makefile
lib/libvmod_unix/Makefile
lib/libvmod_proxy/Makefile
+ lib/libvmod_h2/Makefile
man/Makefile
varnishapi.pc
varnishapi-uninstalled.pc
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 907ee4a5e..986abf890 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -12,4 +12,5 @@ SUBDIRS = \
libvmod_vtc \
libvmod_blob \
libvmod_unix \
- libvmod_proxy
+ libvmod_proxy \
+ libvmod_h2
diff --git a/lib/libvmod_h2/Makefile.am b/lib/libvmod_h2/Makefile.am
new file mode 100644
index 000000000..5013d1de1
--- /dev/null
+++ b/lib/libvmod_h2/Makefile.am
@@ -0,0 +1,3 @@
+
+libvmod_h2_la_SOURCES = vmod_h2.c
+include $(srcdir)/automake_boilerplate.am
diff --git a/lib/libvmod_h2/automake_boilerplate.am b/lib/libvmod_h2/automake_boilerplate.am
new file mode 100644
index 000000000..cf7dc7b1b
--- /dev/null
+++ b/lib/libvmod_h2/automake_boilerplate.am
@@ -0,0 +1,37 @@
+
+# Boilerplate generated by vmodtool.py - changes will be overwritten
+
+AM_LDFLAGS = $(AM_LT_LDFLAGS)
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/bin/varnishd \
+ -I$(top_builddir)/include
+
+vmoddir = $(pkglibdir)/vmods
+vmodtool = $(top_srcdir)/lib/libvcc/vmodtool.py
+vmodtoolargs = --strict --boilerplate
+
+vmod_LTLIBRARIES = libvmod_h2.la
+
+libvmod_h2_la_CFLAGS =
+
+libvmod_h2_la_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ $(VMOD_LDFLAGS)
+
+nodist_libvmod_h2_la_SOURCES = vcc_if.c vcc_if.h
+
+$(libvmod_h2_la_OBJECTS): vcc_if.h
+
+vcc_if.h vmod_h2.rst vmod_h2.man.rst: vcc_if.c
+
+vcc_if.c: $(vmodtool) $(srcdir)/vmod.vcc
+ @PYTHON@ $(vmodtool) $(vmodtoolargs) $(srcdir)/vmod.vcc
+
+EXTRA_DIST = vmod.vcc automake_boilerplate.am
+
+CLEANFILES = $(builddir)/vcc_if.c $(builddir)/vcc_if.h \
+ $(builddir)/vmod_h2.rst \
+ $(builddir)/vmod_h2.man.rst
+
diff --git a/lib/libvmod_h2/vmod.vcc b/lib/libvmod_h2/vmod.vcc
new file mode 100644
index 000000000..65702aaf6
--- /dev/null
+++ b/lib/libvmod_h2/vmod.vcc
@@ -0,0 +1,88 @@
+#-
+# Copyright 2023 UPLEX - Nils Goroll Systemoptimierung
+# All rights reserved.
+#
+# Author: Nils Goroll <nils.goroll at uplex.de>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+$ABI strict
+$Module h2 3 "Module to control the built-in HTTP2 transport"
+
+DESCRIPTION
+===========
+
+This VMOD contains functions to control the HTTP2 transport built into
+Varnish-Cache.
+
+$Function BOOL is()
+
+Returns true when called on a session handled by the built-in HTTP2 transport.
+
+$Function DURATION rapid_reset([DURATION threshold])
+
+Get and optionally set the ``h2_rapid_reset`` parameter (See
+:ref:`varnishd(1)`) for this HTTP2 session only.
+
+Returns -1 when used outside the HTTP2 transport. Otherwise returns
+the previous value.
+
+If the call leads to a change in the rate limit parameters, the
+current budget as retuned by
+`h2.rapid_reset_budget()` is reset.
+
+$Function INT rapid_reset_limit([INT number])
+
+Get and optionally set the ``h2_rapid_reset_limit`` parameter (See
+:ref:`varnishd(1)`) for this HTTP2 session only.
+
+Returns -1 when used outside the HTTP2 transport. Otherwise returns
+the previous value.
+
+If the call leads to a change in the rate limit parameters, the
+current budget as retuned by
+`h2.rapid_reset_budget()` is reset.
+
+$Function DURATION rapid_reset_period([DURATION duration])
+
+Get and optionally set the ``h2_rapid_reset_period`` parameter (See
+:ref:`varnishd(1)`) for this HTTP2 session only.
+
+Returns -1 when used outside the HTTP2 transport. Otherwise returns
+the previous value.
+
+If the call leads to a change in the rate limit parameters, the
+current budget as retuned by
+`h2.rapid_reset_budget()` is reset.
+
+$Function REAL rapid_reset_budget()
+
+Return how many RST frames classified as "rapid" the client is still
+allowed to send before the session is going to be closed.
+
+SEE ALSO
+========
+
+* :ref:`varnishd(1)`
+* :ref:`vsl(7)`
diff --git a/lib/libvmod_h2/vmod_h2.c b/lib/libvmod_h2/vmod_h2.c
new file mode 100644
index 000000000..2153e979e
--- /dev/null
+++ b/lib/libvmod_h2/vmod_h2.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright 2023 UPLEX - Nils Goroll Systemoptimierung
+ * All rights reserved.
+ *
+ * Author: Nils Goroll <nils.goroll at uplex.de>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#include "cache/cache_varnishd.h"
+
+#include "vcc_if.h"
+
+#include "cache/cache_transport.h"
+#include "http2/cache_http2.h"
+
+static struct h2_sess *
+h2get(VRT_CTX)
+{
+ struct h2_sess *h2;
+ uintptr_t *up;
+
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC); // $Restrict client
+ if (ctx->req->transport != &H2_transport)
+ return (NULL);
+ AZ(SES_Get_proto_priv(ctx->req->sp, &up));
+ CAST_OBJ_NOTNULL(h2, (void *)*up, H2_SESS_MAGIC);
+ return (h2);
+}
+VCL_BOOL
+vmod_is(VRT_CTX)
+{
+ struct h2_sess *h2 = h2get(ctx);
+
+ return (h2 != NULL);
+}
+
+#define GETSET(type, name, argname) \
+type \
+vmod_ ## name(VRT_CTX, struct vmod_##name##_arg *args) \
+{ \
+ struct h2_sess *h2 = h2get(ctx); \
+ type r; \
+ \
+ if (h2 == NULL) \
+ return (-1); \
+ \
+ if (! args->valid_ ## argname) \
+ return (h2->name); \
+ if (h2->name == args->argname) \
+ return (h2->name); \
+ \
+ Lck_Lock(&h2->sess->mtx); \
+ r = h2->name; \
+ if (h2->name != args->argname) { \
+ h2->name = args->argname; \
+ h2->rst_budget = h2->rapid_reset_limit; \
+ h2->last_rst = ctx->now; \
+ } \
+ Lck_Unlock(&h2->sess->mtx); \
+ return (r); \
+}
+
+GETSET(VCL_DURATION, rapid_reset, threshold)
+GETSET(VCL_INT, rapid_reset_limit, number)
+GETSET(VCL_DURATION, rapid_reset_period, duration)
+
+VCL_REAL
+vmod_rapid_reset_budget(VRT_CTX)
+{
+ struct h2_sess *h2 = h2get(ctx);
+
+ if (h2 == NULL)
+ return (-1);
+
+ return (h2->rst_budget);
+}
diff --git a/man/Makefile.am b/man/Makefile.am
index 0e35dc5bf..1c2714872 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -21,7 +21,8 @@ dist_man_MANS = \
vmod_vtc.3 \
vmod_blob.3 \
vmod_unix.3 \
- vmod_proxy.3
+ vmod_proxy.3 \
+ vmod_h2.3
CLEANFILES = $(dist_man_MANS)
@@ -109,4 +110,7 @@ vmod_unix.3: $(top_builddir)/lib/libvmod_unix/vmod_unix.man.rst
vmod_proxy.3: $(top_builddir)/lib/libvmod_proxy/vmod_proxy.man.rst
${RST2MAN} $(RST2ANY_FLAGS) $? $@
+vmod_h2.3: $(top_builddir)/lib/libvmod_h2/vmod_h2.man.rst
+ ${RST2MAN} $(RST2ANY_FLAGS) $? $@
+
.NOPATH: $(dist_man_MANS)
More information about the varnish-commit
mailing list