]> err.no Git - varnish/commitdiff
Change the acl syntax slightly: the ( ... ) should enclose all of
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sat, 22 Jul 2006 10:41:00 +0000 (10:41 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sat, 22 Jul 2006 10:41:00 +0000 (10:41 +0000)
the rule (ie: also !  and /mask if present).

Implement matching for IPv4.

Acl tests are shmlogged as follows (doc candidate):

shmlog tag: VCL_actl

"NO_MATCH $acl"
client did not match access list $acl
"FAIL $acl $rule"
getaddrinfo(3) failed on $rule which had a '!'
"MATCH $acl $rule"
client matched $rule
"NEG_MATCH $acl $rule"
client matched negated (!) $rule

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

varnish-cache/bin/varnishd/cache_vrt_acl.c
varnish-cache/include/shmlog_tags.h
varnish-cache/include/vcl_returns.h
varnish-cache/include/vrt.h
varnish-cache/lib/libvcl/vcc_acl.c
varnish-cache/lib/libvcl/vcc_fixed_token.c

index 3a461de6fed06a2ffbb3472c022b1a6ba5763ffb..4674cef26433438ad1d8a4006912f3e880911d0e 100644 (file)
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
+#include <netinet/in.h>
 
 
+static unsigned ipv4mask[] = {
+       [0]     =       0xffffffff,
+#define M(n)   [n] = (0xffffffff << (32 - n))
+        M( 1), M( 2), M( 3), M( 4), M( 5), M( 6), M( 7), M( 8), M( 9), M(10),
+        M(11), M(12), M(13), M(14), M(15), M(16), M(17), M(18), M(19), M(20),
+        M(21), M(22), M(23), M(24), M(25), M(26), M(27), M(28), M(29), M(30),
+        M(31), M(32)
+};
+
+static int
+vrt_acl_vsl(struct sess *sp, const char *acl, struct vrt_acl *ap, int r)
+{
+
+       assert(ap != NULL);
+       if (ap->name == NULL) {
+               assert(r == 0);
+               VSL(SLT_VCL_acl, sp->fd, "NO_MATCH %s", acl);
+               return (r);
+       }
+       if (ap->priv == NULL) {
+               assert(r == 0);
+               VSL(SLT_VCL_acl, sp->fd, "FAIL %s %s", acl, ap->desc);
+               return (r);
+       }
+       
+       VSL(SLT_VCL_acl, sp->fd, "%s %s %s",
+               r ? "MATCH" : "NEG_MATCH", acl, ap->desc);
+       return (r);
+}
+
 int
-VRT_acl_match(struct sess *sp, struct vrt_acl *ap)
+VRT_acl_match(struct sess *sp, const char *acl, struct vrt_acl *ap)
 {
-       (void)sp;
-       (void)ap;
-       return (0);
+       struct addrinfo *a1;
+       struct sockaddr_in *sin1, *sin2;
+
+       if (sp->sockaddr->sa_family == AF_INET) {
+               assert(sp->sockaddrlen >= sizeof *sin1);
+               sin1 = (void*)sp->sockaddr;
+       } else {
+               sin1 = NULL;
+       }
+       
+       for ( ; ap->name != NULL; ap++) {
+               if (ap->priv == NULL && ap->paren)
+                       continue;
+               if (ap->priv == NULL && ap->not) {
+                       return (vrt_acl_vsl(sp, acl, ap, 0));
+               }
+               if (ap->priv == NULL)
+                       continue;
+               for (a1 = ap->priv; a1 != NULL; a1 = a1->ai_next) {
+
+                       /* only match the right family */
+                       if (a1->ai_family != sp->sockaddr->sa_family)
+                               continue;
+
+                       if (a1->ai_family == AF_INET) {
+                               assert(sin1 != NULL);
+                               assert(a1->ai_addrlen >= sizeof (*sin2));
+                               sin2 = (void*)a1->ai_addr;
+                               if (0 == ((
+                                   htonl(sin1->sin_addr.s_addr) ^
+                                   htonl(sin2->sin_addr.s_addr)) &
+                                   ipv4mask[ap->mask > 32 ? 32 : ap->mask]))
+                                       return (
+                                           vrt_acl_vsl(sp, acl, ap, !ap->not));
+                               continue;
+                       }
+
+                       /* Not rules for unknown protos match */
+                       if (ap->not)
+                               return (vrt_acl_vsl(sp, acl, ap, 0));
+               }
+       }
+       return (vrt_acl_vsl(sp, acl, ap, 0));
 }
 
 void
index 78f5a13888759749bed92a457f2c1333eb9c0520..176eb364458aa694a607a09164462c3c929a86da 100644 (file)
@@ -33,6 +33,7 @@ SLTM(RxHeader)
 SLTM(TxHeader)
 SLTM(LostHeader)
 SLTM(TTL)
+SLTM(VCL_acl)
 SLTM(VCL_call)
 SLTM(VCL_trace)
 SLTM(VCL_return)
index 9fa9a14b2261add3d5a060bebed3985515f41b0c..ef965c1ba5b2de0819c784a996977ed8e11c54db 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: vcc_gen_fixed_token.tcl 553 2006-07-21 21:57:43Z phk $
+ * $Id: vcc_gen_fixed_token.tcl 556 2006-07-22 09:38:09Z phk $
  *
  * NB:  This file is machine generated, DO NOT EDIT!
  *
index 9598bb40fafe4d2f9beb03ba4ea794d9d121a66f..73cbcf63b649a31a086beef13ee61b8e8624e7b7 100644 (file)
@@ -20,14 +20,15 @@ struct vrt_ref {
 
 struct vrt_acl {
        unsigned char   not;
-       unsigned char   paren;
        unsigned char   mask;
+       unsigned char   paren;
        const char      *name;
+       const char      *desc;
        void            *priv;
 };
 
 /* ACL related */
-int VRT_acl_match(struct sess *, struct vrt_acl *);
+int VRT_acl_match(struct sess *, const char *, struct vrt_acl *);
 void VRT_acl_init(struct vrt_acl *);
 void VRT_acl_fini(struct vrt_acl *);
 
index 50b0d54801e960db3c4c6b8d0a9a43d6bdfc39d9..13ba8fe16b294e82b14cb8106061b0e97f40b485 100644 (file)
@@ -33,7 +33,7 @@ vcc_Cond_Ip(struct var *vp, struct tokenlist *tl)
                vcc_NextToken(tl);
                ExpectErr(tl, ID);
                AddRef(tl, tl->t, R_ACL);
-               Fc(tl, 1, "VRT_acl_match(sp, acl_%T)\n", tl->t);
+               Fc(tl, 1, "VRT_acl_match(sp, \"%T\", acl_%T)\n", tl->t, tl->t);
                vcc_NextToken(tl);
                break;
        default:
@@ -51,6 +51,7 @@ vcc_Acl(struct tokenlist *tl)
 {
        unsigned mask, para, not;
        struct token *t, *an;
+       char *p;
 
        vcc_NextToken(tl);
 
@@ -71,13 +72,13 @@ vcc_Acl(struct tokenlist *tl)
 
                not = para = mask = 0;
 
-               if (tl->t->tok == '!') {
-                       not = 1;
+               if (tl->t->tok == '(') {
+                       para = 1;
                        vcc_NextToken(tl);
                } 
 
-               if (tl->t->tok == '(') {
-                       para = 1;
+               if (tl->t->tok == '!') {
+                       not = 1;
                        vcc_NextToken(tl);
                } 
 
@@ -90,7 +91,19 @@ vcc_Acl(struct tokenlist *tl)
                        ExpectErr(tl, CNUM);
                        mask = UintVal(tl);
                } 
-               Fc(tl, 1, "{ %u, %u, %u, %T },\n", not, mask, para, t);
+               Fc(tl, 1, "{ %u, %u, %u, %T, \"", not, mask, para, t);
+               if (para)
+                       Fc(tl, 0, "(");
+               if (not)
+                       Fc(tl, 0, "!");
+               p = EncString(t);
+               Fc(tl, 0, "%s", p);
+               free(p);
+               if (mask)
+                       Fc(tl, 0, "/%u", mask);
+               if (para)
+                       Fc(tl, 0, ")");
+               Fc(tl, 0, "\" },\n");
 
                if (para) {
                        ExpectErr(tl, ')');
@@ -99,7 +112,7 @@ vcc_Acl(struct tokenlist *tl)
                ExpectErr(tl, ';');
                vcc_NextToken(tl);
        }
-       Fc(tl, 1, "{ 0, 0, 0, (void*)0}\n", 0, 0);
+       Fc(tl, 1, "{ 0, 0, 0, (void*)0, ""}\n", 0, 0);
        tl->indent -= INDENT;
        Fc(tl, 1, "};\n\n");
 
index 58bef42c3405de7fb4e4202c5efe61b937017a79..4d8870c23b2bec8c9a2f1ff8e11ca44a4a1fa7b2 100644 (file)
@@ -486,14 +486,15 @@ vcl_output_lang_h(FILE *f)
        fputs("\n", f);
        fputs("struct vrt_acl {\n", f);
        fputs(" unsigned char   not;\n", f);
-       fputs(" unsigned char   paren;\n", f);
        fputs(" unsigned char   mask;\n", f);
+       fputs(" unsigned char   paren;\n", f);
        fputs(" const char      *name;\n", f);
+       fputs(" const char      *desc;\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("int VRT_acl_match(struct sess *, const char *, 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);