Same patch, with the missing test case.
From 65a318f2dfe1c6519b9ccd4f154564df76ff281a Mon Sep 17 00:00:00 2001
From: Dridi Boukelmoune <[email protected]>
Date: Thu, 18 Jun 2015 19:00:09 +0200
Subject: [PATCH] Allow ACL references in VMODs
Only log ACL results when the check happens during a transaction.
---
bin/varnishd/cache/cache_vrt.c | 6 ++++--
bin/varnishtest/tests/m00023.vtc | 27 +++++++++++++++++++++++++++
include/vrt.h | 9 +++++++--
lib/libvcc/vcc_acl.c | 17 ++++++++++++-----
lib/libvcc/vcc_compile.h | 1 +
lib/libvcc/vcc_expr.c | 21 +++++++++++++++++++++
lib/libvcc/vmodtool.py | 1 +
lib/libvmod_debug/vmod.vcc | 4 ++++
lib/libvmod_debug/vmod_debug.c | 10 ++++++++++
9 files changed, 87 insertions(+), 9 deletions(-)
create mode 100644 bin/varnishtest/tests/m00023.vtc
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index df6bb96..81b87ba 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -68,8 +68,10 @@ void
VRT_acl_log(VRT_CTX, const char *msg)
{
- CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
- VSLb(ctx->vsl, SLT_VCL_acl, "%s", msg);
+ CHECK_OBJ_ORNULL(ctx, VRT_CTX_MAGIC);
+ AN(msg);
+ if (ctx != NULL && ctx->vsl != NULL)
+ VSLb(ctx->vsl, SLT_VCL_acl, "%s", msg);
}
/*--------------------------------------------------------------------*/
diff --git a/bin/varnishtest/tests/m00023.vtc b/bin/varnishtest/tests/m00023.vtc
new file mode 100644
index 0000000..70ea375
--- /dev/null
+++ b/bin/varnishtest/tests/m00023.vtc
@@ -0,0 +1,27 @@
+varnishtest "Test VMOD ACLs"
+
+varnish v1 -vcl {
+ import ${vmod_debug};
+
+ backend dummy {
+ .host = "${bad_ip}";
+ }
+
+ acl loopback {
+ "127"/24;
+ }
+
+ sub vcl_init {
+ debug.match_acl(loopback, "127.0.0.127");
+ }
+
+ sub vcl_recv {
+ debug.match_acl(loopback, client.ip);
+ return (synth(200));
+ }
+} -start
+
+client c1 {
+ txreq
+ rxresp
+}
diff --git a/include/vrt.h b/include/vrt.h
index 27e738e..c29d5a1 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -54,13 +54,17 @@ struct busyobj;
struct director;
struct http;
struct req;
+struct sess;
struct suckaddr;
struct vcl;
+struct vrt_ctx;
struct vmod;
struct vsb;
struct vsl_log;
struct ws;
+#define VRT_CTX const struct vrt_ctx *ctx
+
/***********************************************************************
* This is the central definition of the mapping from VCL types to
* C-types. The python scripts read these from here.
@@ -82,6 +86,9 @@ typedef const char * VCL_STRING;
typedef double VCL_TIME;
typedef void VCL_VOID;
+typedef int (acl_f) (VRT_CTX, const VCL_IP /* hack */ );
+typedef acl_f * VCL_ACL;
+
/***********************************************************************
* This is the composite argument we pass to compiled VCL and VRT
* functions.
@@ -118,8 +125,6 @@ struct vrt_ctx {
void *specific;
};
-#define VRT_CTX const struct vrt_ctx *ctx
-
/***********************************************************************/
struct vmod_data {
diff --git a/lib/libvcc/vcc_acl.c b/lib/libvcc/vcc_acl.c
index 72dd304..15264be 100644
--- a/lib/libvcc/vcc_acl.c
+++ b/lib/libvcc/vcc_acl.c
@@ -352,7 +352,7 @@ vcc_acl_emit(struct vcc *tl, const char *acln, int anon)
struct token *t;
struct inifin *ifp;
- Fh(tl, 0, "\nstatic int\n");
+ Fh(tl, 0, "\nstatic int __match_proto__(acl_f)\n");
Fh(tl, 0,
"match_acl_%s_%s(VRT_CTX, const VCL_IP p)\n",
anon ? "anon" : "named", acln);
@@ -470,7 +470,7 @@ void
vcc_ParseAcl(struct vcc *tl)
{
struct token *an;
- int i;
+ struct symbol *sym;
char acln[1024];
vcc_NextToken(tl);
@@ -486,13 +486,20 @@ vcc_ParseAcl(struct vcc *tl)
an = tl->t;
vcc_NextToken(tl);
- i = vcc_AddDef(tl, an, SYM_ACL);
- if (i > 1) {
+ bprintf(acln, "%.*s", PF(an));
+
+ sym = VCC_GetSymbolTok(tl, an, SYM_ACL);
+ AN(sym);
+ if (sym->ndef > 0) {
VSB_printf(tl->sb, "ACL %.*s redefined\n", PF(an));
vcc_ErrWhere(tl, an);
return;
}
- bprintf(acln, "%.*s", PF(an));
+ sym->fmt = ACL;
+ sym->eval = vcc_Eval_Acl;
+ sym->eval_priv = TlDup(tl, acln);
+ sym->ndef++;
+ ERRCHK(tl);
SkipToken(tl, '{');
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index a222b9b..9908104 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -278,6 +278,7 @@ sym_expr_t vcc_Eval_Var;
sym_expr_t vcc_Eval_SymFunc;
void vcc_Eval_Func(struct vcc *tl, const char *cfunc, const char *extra,
const char *name, const char *args);
+sym_expr_t vcc_Eval_Acl;
sym_expr_t vcc_Eval_Backend;
/* vcc_obj.c */
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index df5aa43..f6648b8 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -501,10 +501,28 @@ vcc_Eval_BoolConst(struct vcc *tl, struct expr **e, const struct symbol *sym)
*/
void
+vcc_Eval_Acl(struct vcc *tl, struct expr **e, const struct symbol *sym)
+{
+
+ assert(sym->kind == SYM_ACL);
+ AN(sym->eval_priv);
+
+ vcc_ExpectCid(tl);
+ vcc_AddRef(tl, tl->t, SYM_ACL);
+ *e = vcc_mk_expr(ACL, "&match_acl_named_%s",
+ (const char *)sym->eval_priv);
+ (*e)->constant = EXPR_VAR; /* XXX ? */
+ vcc_NextToken(tl);
+}
+/*--------------------------------------------------------------------
+ */
+
+void
vcc_Eval_Backend(struct vcc *tl, struct expr **e, const struct symbol *sym)
{
assert(sym->kind == SYM_BACKEND);
+ AN(sym->eval_priv);
vcc_ExpectCid(tl);
vcc_AddRef(tl, tl->t, SYM_BACKEND);
@@ -809,6 +827,8 @@ vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt)
* XXX: look for SYM_VAR first for consistency ?
*/
sym = NULL;
+ if (fmt == ACL)
+ sym = VCC_FindSymbol(tl, tl->t, SYM_ACL);
if (fmt == BACKEND)
sym = VCC_FindSymbol(tl, tl->t, SYM_BACKEND);
if (sym == NULL)
@@ -829,6 +849,7 @@ vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt)
switch(sym->kind) {
case SYM_VAR:
case SYM_FUNC:
+ case SYM_ACL:
case SYM_BACKEND:
AN(sym->eval);
AZ(*e);
diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py
index a5eb8bb..b27eb23 100755
--- a/lib/libvcc/vmodtool.py
+++ b/lib/libvcc/vmodtool.py
@@ -46,6 +46,7 @@ from os.path import dirname, realpath, exists
from pprint import pprint, pformat
ctypes = {
+ 'ACL': "VCL_ACL",
'BACKEND': "VCL_BACKEND",
'BLOB': "VCL_BLOB",
'BOOL': "VCL_BOOL",
diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc
index 67edd62..e4e1706 100644
--- a/lib/libvmod_debug/vmod.vcc
+++ b/lib/libvmod_debug/vmod.vcc
@@ -105,3 +105,7 @@ Register the vmod to receive expiry callbacks
$Function VOID init_fail()
Function to fail vcl_init{}
+
+$Function VOID match_acl(ACL acl, IP ip)
+
+Panic if ip doesn't match acl.
diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c
index f9f3361..7bc81d0 100644
--- a/lib/libvmod_debug/vmod_debug.c
+++ b/lib/libvmod_debug/vmod_debug.c
@@ -269,3 +269,13 @@ event_function(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
priv->free = priv_vcl_free;
return (0);
}
+
+VCL_VOID
+vmod_match_acl(VRT_CTX, VCL_ACL acl, VCL_IP ip) {
+
+ CHECK_OBJ_ORNULL(ctx, VRT_CTX_MAGIC);
+ AN(acl);
+ AN(ip);
+
+ AN(acl(ctx, ip));
+}
--
2.1.0
_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev