[master] 1d52b52a5 Implement a real DAG-loop detector for allowing VCL labels
Poul-Henning Kamp
phk at FreeBSD.org
Tue May 28 09:08:12 UTC 2019
commit 1d52b52a5cc85134ad90ec60daa52cd779b2f026
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue May 28 09:02:47 2019 +0000
Implement a real DAG-loop detector for allowing VCL labels
diff --git a/bin/varnishd/mgt/mgt_symtab.c b/bin/varnishd/mgt/mgt_symtab.c
index 64c1bef4d..e54274c8c 100644
--- a/bin/varnishd/mgt/mgt_symtab.c
+++ b/bin/varnishd/mgt/mgt_symtab.c
@@ -235,14 +235,14 @@ mcf_vcl_symtab(struct cli *cli, const char * const *av, void *priv)
VTAILQ_FOREACH(vp, &vclhead, list) {
VCLI_Out(cli, "VCL: %s\n", vp->name);
VCLI_Out(cli, " imports from:\n");
- VTAILQ_FOREACH(vd, &vp->dto, lto) {
- VCLI_Out(cli, " %s\n", vd->from->name);
+ VTAILQ_FOREACH(vd, &vp->dfrom, lfrom) {
+ VCLI_Out(cli, " %s\n", vd->to->name);
if (vd->vj)
mcf_vcl_vjsn_dump(cli, vd->vj, 6);
}
VCLI_Out(cli, " exports to:\n");
- VTAILQ_FOREACH(vd, &vp->dfrom, lfrom) {
- VCLI_Out(cli, " %s\n", vd->to->name);
+ VTAILQ_FOREACH(vd, &vp->dto, lto) {
+ VCLI_Out(cli, " %s\n", vd->from->name);
if (vd->vj)
mcf_vcl_vjsn_dump(cli, vd->vj, 6);
}
diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index 47b223496..80404fee6 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -802,6 +802,27 @@ mcf_vcl_list_json(struct cli *cli, const char * const *av, void *priv)
}
}
+static int
+mcf_vcl_check_dag(struct cli *cli, struct vclprog *tree, struct vclprog *target)
+{
+ struct vcldep *vd;
+
+ if (target == tree)
+ return (1);
+ VTAILQ_FOREACH(vd, &tree->dfrom, lfrom) {
+ if (!mcf_vcl_check_dag(cli, vd->to, target))
+ continue;
+ if (mcf_is_label(tree))
+ VCLI_Out(cli, "Label %s points to vcl %s\n",
+ tree->name, vd->to->name);
+ else
+ VCLI_Out(cli, "Vcl %s uses Label %s\n",
+ tree->name, vd->to->name);
+ return (1);
+ }
+ return(0);
+}
+
static void v_matchproto_(cli_func_t)
mcf_vcl_label(struct cli *cli, const char * const *av, void *priv)
{
@@ -814,8 +835,12 @@ mcf_vcl_label(struct cli *cli, const char * const *av, void *priv)
(void)priv;
if (mcf_invalid_vclname(cli, av[2]))
return;
- if (mcf_invalid_vclname(cli, av[3]))
+ vpl = mcf_vcl_byname(av[2]);
+ if (vpl != NULL && !mcf_is_label(vpl)) {
+ VCLI_SetResult(cli, CLIS_PARAM);
+ VCLI_Out(cli, "%s is not a label", vpl->name);
return;
+ }
vpt = mcf_find_vcl(cli, av[3]);
if (vpt == NULL)
return;
@@ -824,23 +849,13 @@ mcf_vcl_label(struct cli *cli, const char * const *av, void *priv)
VCLI_Out(cli, "VCL labels cannot point to labels");
return;
}
- vpl = mcf_vcl_byname(av[2]);
if (vpl != NULL) {
- if (!mcf_is_label(vpl)) {
- VCLI_SetResult(cli, CLIS_PARAM);
- VCLI_Out(cli, "%s is not a label", vpl->name);
- return;
- }
- if (!VTAILQ_EMPTY(&vpt->dfrom) &&
- !VTAILQ_EMPTY(&vpl->dto)) {
- VCLI_SetResult(cli, CLIS_PARAM);
- VCLI_Out(cli, "return(vcl) can only be used from"
- " the active VCL.\n\n");
+ if (VTAILQ_FIRST(&vpl->dfrom)->to != vpt &&
+ mcf_vcl_check_dag(cli, vpt, vpl)) {
VCLI_Out(cli,
- "Label %s is used in return(vcl) from VCL %s\n",
- vpl->name, VTAILQ_FIRST(&vpl->dto)->from->name);
- VCLI_Out(cli, "and VCL %s also has return(vcl)",
- vpt->name);
+ "Pointing label %s at %s would create a loop",
+ vpl->name, vpt->name);
+ VCLI_SetResult(cli, CLIS_PARAM);
return;
}
}
diff --git a/bin/varnishtest/tests/c00077.vtc b/bin/varnishtest/tests/c00077.vtc
index 060d577f9..c25d9e4c5 100644
--- a/bin/varnishtest/tests/c00077.vtc
+++ b/bin/varnishtest/tests/c00077.vtc
@@ -60,6 +60,8 @@ varnish v1 -clierr 300 "vcl.discard vclA"
varnish v1 -vcl+backend { }
+varnish v1 -clierr 106 "vcl.label vclA vcl3"
+
varnish v1 -cliok "vcl.symtab"
varnish v1 -cliok "vcl.discard vcl3"
diff --git a/bin/varnishtest/tests/s00005.vtc b/bin/varnishtest/tests/s00005.vtc
index 01c2def7e..0fa00990f 100644
--- a/bin/varnishtest/tests/s00005.vtc
+++ b/bin/varnishtest/tests/s00005.vtc
@@ -127,6 +127,6 @@ varnish v1 -vcl+backend { sub vcl_recv { return (vcl(lblB)); } }
varnish v1 -clierr 106 "vcl.label lblA vcl5"
varnish v1 -cliexpect \
- {can only be used from the active VCL} \
+ {would create a loop} \
{vcl.label lblA vcl5}
More information about the varnish-commit
mailing list