]> err.no Git - varnish/commitdiff
VCL compiler:
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sat, 22 Jul 2006 09:38:09 +0000 (09:38 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sat, 22 Jul 2006 09:38:09 +0000 (09:38 +0000)
add two sbufs for "init" and "fini" actions.

VCL ACLs:  Change syntax and implementation as follows.

ACL Syntax now works the following way:

acl $name {
! ( "myhost.com" ) ;
"10.0.0.1" /8 ;
}

The '!' means not.  If the address matches the rest of the rule
the address does NOT match the acl and the search terminates here.

Enclosing the string in paranthesis means that the rule will be ignored
if the string cannot be converted to an address (with getaddrinfo).

When a string can not be looked up, and is not enclosed in a
paranthesis, a positive rule (ie: without !) will not match and a
negative rule (with !) will match.

A mask can always be supplied, no matter the style of the string
given, so it is possible to do things like:

{ "fw.ourcompany.dom" / 24 }

Which means "any host on the same /24 subnet as fw.ourcompany.dom".

Unfortunately getaddrinfo() does not return a TTL for the results,
in the future we may want to use some kind of timeout to refresh
the lookups.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@556 d4fa192b-c00b-0410-8231-f00ffab90ce4

12 files changed:
varnish-cache/bin/varnishd/Makefile.am
varnish-cache/bin/varnishd/cache_vrt.c
varnish-cache/bin/varnishd/cache_vrt_acl.c [new file with mode: 0644]
varnish-cache/include/vcl.h
varnish-cache/include/vcl_returns.h
varnish-cache/include/vrt.h
varnish-cache/include/vrt_obj.h
varnish-cache/lib/libvcl/vcc_acl.c
varnish-cache/lib/libvcl/vcc_compile.c
varnish-cache/lib/libvcl/vcc_compile.h
varnish-cache/lib/libvcl/vcc_fixed_token.c
varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl

index 489e3fbdbe3894ac4f912cf5e2b1fa20030a4359..1d53f9467e65f4d7e979f1eeb03c77371de42ede 100644 (file)
@@ -30,6 +30,7 @@ varnishd_SOURCES = \
        cache_session.c \
        cache_vcl.c \
        cache_vrt.c \
+       cache_vrt_acl.c \
        cli_event.c \
        hash_simple_list.c \
        hash_classic.c \
index 2e46f8431e7ded6af524fa5d9c35c001785c072f..254c32868ed5dc69ee744995749ba5f517e9b989 100644 (file)
@@ -86,6 +86,19 @@ VRT_alloc_backends(struct VCL_conf *cp)
        }
 }
 
+void
+VRT_free_backends(struct VCL_conf *cp)
+{
+
+       (void)cp;
+}
+
+void
+VRT_fini_backend(struct backend *be)
+{
+       (void)be;
+}
+
 /*--------------------------------------------------------------------*/
 
 #define VBACKEND(type,onm,field)                       \
diff --git a/varnish-cache/bin/varnishd/cache_vrt_acl.c b/varnish-cache/bin/varnishd/cache_vrt_acl.c
new file mode 100644 (file)
index 0000000..3a461de
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * $Id$
+ *
+ * Runtime support for compiled VCL programs, ACLs
+ *
+ * XXX: getaddrinfo() does not return a TTL.  We might want to add
+ * XXX: a refresh facility.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "shmlog.h"
+#include "vrt.h"
+#include "vrt_obj.h"
+#include "vcl.h"
+#include "cache.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+
+int
+VRT_acl_match(struct sess *sp, struct vrt_acl *ap)
+{
+       (void)sp;
+       (void)ap;
+       return (0);
+}
+
+void
+VRT_acl_init(struct vrt_acl *ap)
+{
+       struct addrinfo a0, *a1;
+       int i;
+
+       memset(&a0, 0, sizeof a0);
+       a0.ai_socktype = SOCK_STREAM;
+
+       for ( ; ap->name != NULL; ap++) {
+               a1 = NULL;
+               i = getaddrinfo(ap->name, NULL, &a0, &a1);
+               if (i != 0) {
+                       fprintf(stderr, "getaddrinfo(%s) = %s\n",
+                           ap->name, gai_strerror(i));
+                       if (a1 != NULL) 
+                               freeaddrinfo(a1);
+                       a1 = NULL;
+               }
+               ap->priv = a1;
+       }
+}
+
+void
+VRT_acl_fini(struct vrt_acl *ap)
+{
+       struct addrinfo *a1;
+
+       for ( ; ap->name != NULL; ap++) {
+               if (ap->priv == NULL)
+                       continue;
+               a1 = ap->priv;
+               ap->priv = NULL;
+               freeaddrinfo(a1);
+       }
+}
+
+
index eb32322407723c82d1b79b5a2d3974af1b8676ef..a6c78957b148de33bcd908d7ab790fafa8989682 100644 (file)
@@ -9,6 +9,7 @@
 struct sess;
 
 typedef void vcl_init_f(void);
+typedef void vcl_fini_f(void);
 typedef int vcl_func_f(struct sess *sp);
 
 struct VCL_conf {
@@ -22,6 +23,7 @@ struct VCL_conf {
         unsigned        busy;
 
         vcl_init_f      *init_func;
+        vcl_fini_f      *fini_func;
 
        vcl_func_f      *recv_func;
        vcl_func_f      *miss_func;
index 1fef265e392e9d5d35f5df8993b36f367a5e72ed..9fa9a14b2261add3d5a060bebed3985515f41b0c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: vcc_gen_fixed_token.tcl 545 2006-07-21 20:43:56Z phk $
+ * $Id: vcc_gen_fixed_token.tcl 553 2006-07-21 21:57:43Z phk $
  *
  * NB:  This file is machine generated, DO NOT EDIT!
  *
index 69cfe85286ada986808d10ec64d1d18e3ee20bc9..9598bb40fafe4d2f9beb03ba4ea794d9d121a66f 100644 (file)
@@ -19,15 +19,19 @@ struct vrt_ref {
 };
 
 struct vrt_acl {
-       unsigned        ip;
-       unsigned        mask;
+       unsigned char   not;
+       unsigned char   paren;
+       unsigned char   mask;
+       const char      *name;
+       void            *priv;
 };
 
+/* ACL related */
+int VRT_acl_match(struct sess *, struct vrt_acl *);
+void VRT_acl_init(struct vrt_acl *);
+void VRT_acl_fini(struct vrt_acl *);
+
 void VRT_count(struct sess *, unsigned);
-#if 0
-int ip_match(unsigned, struct vcl_acl *);
-int string_match(const char *, const char *);
-#endif
 int VRT_rewrite(const char *, const char *);
 void VRT_error(struct sess *, unsigned, const char *);
 int VRT_switch_config(const char *);
@@ -35,9 +39,12 @@ int VRT_switch_config(const char *);
 char *VRT_GetHdr(struct sess *, const char *);
 void VRT_handling(struct sess *sp, unsigned hand);
 
+/* Backend related */
 void VRT_set_backend_name(struct backend *, const char *);
-
 void VRT_alloc_backends(struct VCL_conf *cp);
+void VRT_free_backends(struct VCL_conf *cp);
+void VRT_fini_backend(struct backend *be);
+
 
 #define VRT_done(sp, hand)                     \
        do {                                    \
index 9ab2334c3b90e2902e5b234a19ba35634c14848a..8bb9da11eccc56b0d6d63217851f0b393e7524f1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: vcc_gen_obj.tcl 550 2006-07-21 21:13:43Z phk $
+ * $Id: vcc_gen_obj.tcl 555 2006-07-22 08:02:47Z phk $
  *
  * NB:  This file is machine generated, DO NOT EDIT!
  *
index 128260b427971a925562b51f7be353c5fb78a9e9..50b0d54801e960db3c4c6b8d0a9a43d6bdfc39d9 100644 (file)
 
 #include "libvcl.h"
 
-unsigned
-vcc_IpVal(struct tokenlist *tl)
-{
-       unsigned u, v;
-       struct token *t;
-
-       t = tl->t;
-       u = UintVal(tl);
-       if (u < 256) {
-               v = u << 24;
-               Expect(tl, '.');
-               vcc_NextToken(tl);
-               t = tl->t;
-               u = UintVal(tl);
-               if (u < 256) {
-                       v |= u << 16;
-                       Expect(tl, '.');
-                       vcc_NextToken(tl);
-                       t = tl->t;
-                       u = UintVal(tl);
-                       if (u < 256) {
-                               v |= u << 8;
-                               Expect(tl, '.');
-                               vcc_NextToken(tl);
-                               t = tl->t;
-                               u = UintVal(tl);
-                               if (u < 256) {
-                                       v |= u;
-                                       return (v);
-                               }
-                       }
-               }
-       }
-       sbuf_printf(tl->sb, "Illegal octet in IP number\n");
-       vcc_ErrWhere(tl, t);
-       return (0);
-}
-
 void
 vcc_Cond_Ip(struct var *vp, struct tokenlist *tl)
 {
-       unsigned u;
+
+       (void)vp;       /* only client.ip at this time */
 
        switch (tl->t->tok) {
        case '~':
                vcc_NextToken(tl);
                ExpectErr(tl, ID);
                AddRef(tl, tl->t, R_ACL);
-               Fc(tl, 1, "ip_match(%s, acl_%T)\n", vp->rname, tl->t);
-               vcc_NextToken(tl);
-               break;
-       case T_EQ:
-       case T_NEQ:
-               Fc(tl, 1, "%s %T ", vp->rname, tl->t);
+               Fc(tl, 1, "VRT_acl_match(sp, acl_%T)\n", tl->t);
                vcc_NextToken(tl);
-               u = vcc_IpVal(tl);
-               Fc(tl, 0, "%uU /* %u.%u.%u.%u */\n", u,
-                   (u >> 24) & 0xff, (u >> 16) & 0xff,
-                   (u >> 8) & 0xff, (u) & 0xff);
                break;
        default:
                sbuf_printf(tl->sb, "Illegal condition ");
@@ -95,41 +49,63 @@ vcc_Cond_Ip(struct var *vp, struct tokenlist *tl)
 void
 vcc_Acl(struct tokenlist *tl)
 {
-       unsigned u, m;
+       unsigned mask, para, not;
+       struct token *t, *an;
 
        vcc_NextToken(tl);
 
        ExpectErr(tl, ID);
-       AddDef(tl, tl->t, R_ACL);
-       Fh(tl, 0, "static struct vcl_acl acl_%T[];\n", tl->t);
-       Fc(tl, 1, "static struct vcl_acl acl_%T[] = {\n", tl->t);
+       an = tl->t;
        vcc_NextToken(tl);
 
+       AddDef(tl, an, R_ACL);
+       Fh(tl, 0, "static struct vrt_acl acl_%T[];\n", an);
+       Fc(tl, 1, "static struct vrt_acl acl_%T[] = {\n", an);
+
        tl->indent += INDENT;
 
        ExpectErr(tl, '{');
        vcc_NextToken(tl);
 
-       while (tl->t->tok == CNUM) {
-               u = vcc_IpVal(tl);
+       while (tl->t->tok != '}') {
+
+               not = para = mask = 0;
+
+               if (tl->t->tok == '!') {
+                       not = 1;
+                       vcc_NextToken(tl);
+               } 
+
+               if (tl->t->tok == '(') {
+                       para = 1;
+                       vcc_NextToken(tl);
+               } 
+
+               ExpectErr(tl, CSTR);
+               /* XXX: try to look it up, warn if failure */
+               t = tl->t;
+               vcc_NextToken(tl);
                if (tl->t->tok == '/') {
                        vcc_NextToken(tl);
                        ExpectErr(tl, CNUM);
-                       m = UintVal(tl);
-               } else
-                       m = 32;
+                       mask = UintVal(tl);
+               } 
+               Fc(tl, 1, "{ %u, %u, %u, %T },\n", not, mask, para, t);
+
+               if (para) {
+                       ExpectErr(tl, ')');
+                       vcc_NextToken(tl);
+               }
                ExpectErr(tl, ';');
                vcc_NextToken(tl);
-               Fc(tl, 1, "{ %11uU, %3uU }, /* %u.%u.%u.%u/%u */\n",
-                   u, m,
-                   (u >> 24) & 0xff, (u >> 16) & 0xff,
-                   (u >> 8) & 0xff, (u) & 0xff, m);
        }
-       ExpectErr(tl, '}');
-       Fc(tl, 1, "{ %11uU, %3uU }\n", 0, 0);
-
+       Fc(tl, 1, "{ 0, 0, 0, (void*)0}\n", 0, 0);
        tl->indent -= INDENT;
-
        Fc(tl, 1, "};\n\n");
+
+       ExpectErr(tl, '}');
        vcc_NextToken(tl);
+
+       Fi(tl, 1, "\tVRT_acl_init(acl_%T);\n", an);
+       Ff(tl, 1, "\tVRT_acl_fini(acl_%T);\n", an);
 }
index 0f5b0262353d2e62bee3f669d9d61afe0c4b96eb..7b3caf07ed22404605670fe780453c8fc1320049 100644 (file)
@@ -114,9 +114,33 @@ Fc(struct tokenlist *tl, int indent, const char *fmt, ...)
        va_end(ap);
 }
 
+void
+Fi(struct tokenlist *tl, int indent, const char *fmt, ...)
+{
+       va_list ap;
+
+       if (indent)
+               sbuf_printf(tl->fi, "%*.*s", tl->indent, tl->indent, "");
+       va_start(ap, fmt);
+       sbuf_vprintf(tl->fi, fmt, ap);
+       va_end(ap);
+}
+
+void
+Ff(struct tokenlist *tl, int indent, const char *fmt, ...)
+{
+       va_list ap;
+
+       if (indent)
+               sbuf_printf(tl->ff, "%*.*s", tl->indent, tl->indent, "");
+       va_start(ap, fmt);
+       sbuf_vprintf(tl->ff, fmt, ap);
+       va_end(ap);
+}
+
 /*--------------------------------------------------------------------*/
 
-static char *
+char *
 EncString(struct token *t)
 {
        char *p, *q;
@@ -871,11 +895,11 @@ Backend(struct tokenlist *tl)
                AddRef(tl, tl->t, R_BACKEND);
        Fh(tl, 1, "#define VGC_backend_%T (VCL_conf.backend[%d])\n",
            tl->t, tl->nbackend);
+       Fc(tl, 0, "\n");
        Fc(tl, 0, "static void\n");
        Fc(tl, 1, "VGC_init_backend_%T (void)\n", tl->t);
        Fc(tl, 1, "{\n");
        Fc(tl, 1, "\tstruct backend *backend = VGC_backend_%T;\n", tl->t);
-       Fc(tl, 1, "\tconst char *p;\n");
        Fc(tl, 1, "\n");
        Fc(tl, 1, "\tVRT_set_backend_name(backend, \"%T\");\n", tl->t);
        vcc_NextToken(tl);
@@ -941,6 +965,8 @@ Backend(struct tokenlist *tl)
        vcc_NextToken(tl);
        Fc(tl, 1, "}\n");
        Fc(tl, 0, "\n");
+       Fi(tl, 0, "\tVGC_init_backend_%T();\n", t_be);
+       Ff(tl, 0, "\tVRT_fini_backend(VGC_backend_%T);\n", t_be);
        tl->nbackend++;
 }
 
@@ -1208,22 +1234,20 @@ LocTable(struct tokenlist *tl)
 static void
 EmitInitFunc(struct tokenlist *tl)
 {
-       struct ref *r;
 
        Fc(tl, 0, "\nstatic void\nVGC_Init(void)\n{\n\n");
-       Fc(tl, 0, "\tVRT_alloc_backends(&VCL_conf);\n");
-       
-       TAILQ_FOREACH(r, &tl->refs, list) {
-               switch(r->type) {
-               case R_FUNC:
-                       break;
-               case R_ACL:
-                       break;
-               case R_BACKEND:
-                       Fc(tl, 0, "\tVGC_init_backend_%T();\n", r->name);
-                       break;
-               }
-       }
+       sbuf_finish(tl->fi);
+       sbuf_cat(tl->fc, sbuf_data(tl->fi));
+       Fc(tl, 0, "}\n");
+}
+
+static void
+EmitFiniFunc(struct tokenlist *tl)
+{
+
+       Fc(tl, 0, "\nstatic void\nVGC_Fini(void)\n{\n\n");
+       sbuf_finish(tl->ff);
+       sbuf_cat(tl->fc, sbuf_data(tl->ff));
        Fc(tl, 0, "}\n");
 }
 
@@ -1236,6 +1260,7 @@ EmitStruct(struct tokenlist *tl)
        Fc(tl, 0, "\nstruct VCL_conf VCL_conf = {\n");
        Fc(tl, 0, "\t.magic = VCL_CONF_MAGIC,\n");
        Fc(tl, 0, "\t.init_func = VGC_Init,\n");
+       Fc(tl, 0, "\t.fini_func = VGC_Fini,\n");
        Fc(tl, 0, "\t.nbackend = %d,\n", tl->nbackend);
        Fc(tl, 0, "\t.ref = VGC_ref,\n");
        Fc(tl, 0, "\t.nref = VGC_NREFS,\n");
@@ -1279,8 +1304,16 @@ VCC_Compile(struct sbuf *sb, const char *b, const char *e)
        tokens.fh = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
        assert(tokens.fh != NULL);
 
+       tokens.fi = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
+       assert(tokens.fi != NULL);
+
+       tokens.ff = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
+       assert(tokens.ff != NULL);
+
        Fh(&tokens, 0, "extern struct VCL_conf VCL_conf;\n");
 
+       Fi(&tokens, 0, "\tVRT_alloc_backends(&VCL_conf);\n");
+
        tokens.b = b;
        if (e == NULL)
                e = strchr(b, '\0');
@@ -1300,8 +1333,12 @@ VCC_Compile(struct sbuf *sb, const char *b, const char *e)
                goto done;
        LocTable(&tokens);
 
+       Ff(&tokens, 0, "\tVRT_free_backends(&VCL_conf);\n");
+
        EmitInitFunc(&tokens);
 
+       EmitFiniFunc(&tokens);
+
        EmitStruct(&tokens);
 
        if (CheckRefs(&tokens))
index fd13be1e50d39b6a4dd9ca90175404b0899db27b..0ddfa437ea3fc26e7a0c1144a92f978e6ec6e924 100644 (file)
@@ -22,7 +22,7 @@ struct tokenlist {
        struct token            *t;
        int                     indent;
        unsigned                cnt;
-       struct sbuf             *fc, *fh;
+       struct sbuf             *fc, *fh, *fi, *ff;
        TAILQ_HEAD(, ref)       refs;
        struct sbuf             *sb;
        int                     err;
@@ -97,16 +97,19 @@ struct proc {
 /* vcc_acl.c */
 
 void vcc_Acl(struct tokenlist *tl);
-unsigned vcc_IpVal(struct tokenlist *tl);
 void vcc_Cond_Ip(struct var *vp, struct tokenlist *tl);
 
 /* vcc_compile.c */
 extern const char *vcc_default_vcl_b, *vcc_default_vcl_e;
 void Fh(struct tokenlist *tl, int indent, const char *fmt, ...);
 void Fc(struct tokenlist *tl, int indent, const char *fmt, ...);
+void Fi(struct tokenlist *tl, int indent, const char *fmt, ...);
+void Ff(struct tokenlist *tl, int indent, const char *fmt, ...);
 unsigned UintVal(struct tokenlist *tl);
 void AddDef(struct tokenlist *tl, struct token *t, enum ref_type type);
 void AddRef(struct tokenlist *tl, struct token *t, enum ref_type type);
+char *EncString(struct token *t);
+
 
 /* vcc_obj.c */
 extern struct var vcc_be_vars[];
index c5db22e73e08dbaaff6f5360c34658adde2d0370..58bef42c3405de7fb4e4202c5efe61b937017a79 100644 (file)
@@ -442,6 +442,7 @@ vcl_output_lang_h(FILE *f)
        fputs("struct sess;\n", f);
        fputs("\n", f);
        fputs("typedef void vcl_init_f(void);\n", f);
+       fputs("typedef void vcl_fini_f(void);\n", f);
        fputs("typedef int vcl_func_f(struct sess *sp);\n", f);
        fputs("\n", f);
        fputs("struct VCL_conf {\n", f);
@@ -455,6 +456,7 @@ vcl_output_lang_h(FILE *f)
        fputs("        unsigned        busy;\n", f);
        fputs("\n", f);
        fputs("        vcl_init_f      *init_func;\n", f);
+       fputs("        vcl_fini_f      *fini_func;\n", f);
        fputs("\n", f);
        fputs(" vcl_func_f      *recv_func;\n", f);
        fputs(" vcl_func_f      *miss_func;\n", f);
@@ -483,15 +485,19 @@ vcl_output_lang_h(FILE *f)
        fputs("};\n", f);
        fputs("\n", f);
        fputs("struct vrt_acl {\n", f);
-       fputs(" unsigned        ip;\n", f);
-       fputs(" unsigned        mask;\n", f);
+       fputs(" unsigned char   not;\n", f);
+       fputs(" unsigned char   paren;\n", f);
+       fputs(" unsigned char   mask;\n", f);
+       fputs(" const char      *name;\n", f);
+       fputs(" void            *priv;\n", f);
        fputs("};\n", f);
        fputs("\n", f);
+       fputs("/* ACL related */\n", f);
+       fputs("int VRT_acl_match(struct sess *, struct vrt_acl *);\n", f);
+       fputs("void VRT_acl_init(struct vrt_acl *);\n", f);
+       fputs("void VRT_acl_fini(struct vrt_acl *);\n", f);
+       fputs("\n", f);
        fputs("void VRT_count(struct sess *, unsigned);\n", f);
-       fputs("#if 0\n", f);
-       fputs("int ip_match(unsigned, struct vcl_acl *);\n", f);
-       fputs("int string_match(const char *, const char *);\n", f);
-       fputs("#endif\n", f);
        fputs("int VRT_rewrite(const char *, const char *);\n", f);
        fputs("void VRT_error(struct sess *, unsigned, const char *);\n", f);
        fputs("int VRT_switch_config(const char *);\n", f);
@@ -499,9 +505,12 @@ vcl_output_lang_h(FILE *f)
        fputs("char *VRT_GetHdr(struct sess *, const char *);\n", f);
        fputs("void VRT_handling(struct sess *sp, unsigned hand);\n", f);
        fputs("\n", f);
+       fputs("/* Backend related */\n", f);
        fputs("void VRT_set_backend_name(struct backend *, const char *);\n", f);
-       fputs("\n", f);
        fputs("void VRT_alloc_backends(struct VCL_conf *cp);\n", f);
+       fputs("void VRT_free_backends(struct VCL_conf *cp);\n", f);
+       fputs("void VRT_fini_backend(struct backend *be);\n", f);
+       fputs("\n", f);
        fputs("\n", f);
        fputs("#define VRT_done(sp, hand)                       \\\n", f);
        fputs(" do {                                    \\\n", f);
index 1a087bad629ee2fb977969873fdc08f5aa6d2e6d..ce827693d61e7776818370dac075974dd426112b 100755 (executable)
@@ -97,6 +97,7 @@ warns $fo
 puts $fo {struct sess;
 
 typedef void vcl_init_f(void);
+typedef void vcl_fini_f(void);
 typedef int vcl_func_f(struct sess *sp);
 }
 puts $fo "struct VCL_conf {"
@@ -110,6 +111,7 @@ puts $fo {  unsigned        magic;
         unsigned        busy;
 
         vcl_init_f      *init_func;
+        vcl_fini_f      *fini_func;
 }
 foreach m $methods {
        puts $fo "\tvcl_func_f\t*[lindex $m 0]_func;"