[master] a91e16ed5 Add VPI interface for runtime recursion tracking & checks

Nils Goroll nils.goroll at uplex.de
Mon Feb 8 17:52:04 UTC 2021


commit a91e16ed5bba1ffd6aec494f8976823c0254289d
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Sun Jan 31 12:51:46 2021 +0100

    Add VPI interface for runtime recursion tracking & checks
    
    This implements the first bit of phks suggestion in
    https://github.com/varnishcache/varnish-cache/pull/3163#issuecomment-769718143
    
    These VPI functions implement the operations on the recursion check
    bitmask for dynamic SUB calls. Strictly speaking, the VPI subs would
    not need to be concerned with the methods bitmask check and the
    assertion that calls originate from the right VCL, but we centralise
    these aspects for simplicity.
    
    We also add an enum to denote check failures.

diff --git a/bin/varnishd/cache/cache_vpi.c b/bin/varnishd/cache/cache_vpi.c
index 24a3c58b9..f6e09dd86 100644
--- a/bin/varnishd/cache/cache_vpi.c
+++ b/bin/varnishd/cache/cache_vpi.c
@@ -35,6 +35,7 @@
 #include "cache_varnishd.h"
 
 #include "vcl.h"
+#include "vbm.h"
 
 #include "vcc_interface.h"
 
@@ -140,3 +141,48 @@ VPI_Fail(const char *func, const char *file, int line,
 {
 	VAS_Fail(func, file, line, cond, VAS_ASSERT);
 }
+
+enum vcl_func_fail_e
+VPI_Call_Check(VRT_CTX, const struct VCL_conf *conf,
+    unsigned methods, unsigned n)
+{
+	struct vbitmap *vbm;
+
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	CHECK_OBJ_NOTNULL(ctx->vcl, VCL_MAGIC);
+
+	assert(conf == ctx->vcl->conf);
+
+	vbm = ctx->called;
+	AN(vbm);
+
+	if ((methods & ctx->method) == 0)
+		return (VSUB_E_METHOD);
+
+	if (vbit_test(vbm, n))
+		return (VSUB_E_RECURSE);
+
+	return (VSUB_E_OK);
+}
+
+void
+VPI_Call_Begin(VRT_CTX, unsigned n)
+{
+	struct vbitmap *vbm;
+
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	vbm = ctx->called;
+	AN(vbm);
+	vbit_set(vbm, n);
+}
+
+void
+VPI_Call_End(VRT_CTX, unsigned n)
+{
+	struct vbitmap *vbm;
+
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	vbm = ctx->called;
+	AN(vbm);
+	vbit_clr(vbm, n);
+}
diff --git a/include/vcc_interface.h b/include/vcc_interface.h
index 4c2a5c295..7ad670ea3 100644
--- a/include/vcc_interface.h
+++ b/include/vcc_interface.h
@@ -95,3 +95,8 @@ struct vcl_sub {
 	unsigned		nref;
 	unsigned		called;
 };
+
+enum vcl_func_fail_e VPI_Call_Check(VRT_CTX, const struct VCL_conf *conf,
+    unsigned methods, unsigned n);
+void VPI_Call_Begin(VRT_CTX, unsigned n);
+void VPI_Call_End(VRT_CTX, unsigned n);
diff --git a/include/vrt.h b/include/vrt.h
index c95d0f820..ffb6d2abc 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -339,6 +339,12 @@ struct vrt_ctx {
 #define VRT_CTX		const struct vrt_ctx *ctx
 void VRT_CTX_Assert(VRT_CTX);
 
+enum vcl_func_fail_e {
+	VSUB_E_OK,
+	VSUB_E_RECURSE, // call would recurse
+	VSUB_E_METHOD	// can not be called from this method
+};
+
 typedef void vcl_func_f(VRT_CTX);
 
 /***********************************************************************


More information about the varnish-commit mailing list