Revision: 14778
Author: adrian.chadd
Date: Sat Sep  4 05:24:18 2010
Log: Merge r13325 from /playpen/ipv6_acl

Initial IPv6 ACL framework commit. This introduces the basic IPv6 ACL config processing.

* change aclIpDataPool() to use sqaddr_t instead of struct in_addr;
* rename decode_addr() to decode_v4_addr(); so it only decodes v4 addresses;
* aclMatchIp() still only takes an in_addr; it matches only on IPv4 addresses
  for the time being;
* aclParseIpData() still only does IPv4 DNS lookups and IPv4 record generation,
  even though its mostly IPv4/IPv6 agnostic.



http://code.google.com/p/lusca-cache/source/detail?r=14778

Modified:
 /playpen/LUSCA_HEAD_ipv6/src/acl.c
 /playpen/LUSCA_HEAD_ipv6/src/structs.h

=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/acl.c  Thu Sep  2 18:24:55 2010
+++ /playpen/LUSCA_HEAD_ipv6/src/acl.c  Sat Sep  4 05:24:18 2010
@@ -67,7 +67,7 @@
 static void aclParseHeader(void *data);
 static void aclDestroyHeader(void *data);
 static squid_acl aclStrToType(const char *s);
-static int decode_addr(const char *, struct in_addr *);
+static int decode_v4_addr(const char *, sqaddr_t *);
 static void aclCheck(aclCheck_t * checklist);
 static void aclCheckCallback(aclCheck_t * checklist, allow_t answer);
 #if USE_IDENT
@@ -457,27 +457,29 @@
  * This function should NOT be called if 'asc' is a hostname!
  */
 static int
-decode_addr(const char *asc, struct in_addr *addr)
-{
+decode_v4_addr(const char *asc, sqaddr_t *A)
+{
+    struct in_addr addr;
     int a1 = 0, a2 = 0, a3 = 0, a4 = 0;

     switch (sscanf(asc, "%d.%d.%d.%d", &a1, &a2, &a3, &a4)) {
     case 4:                    /* a dotted quad */
-       if (!safe_inet_addr(asc, addr)) {
-           debug(28, 0) ("decode_addr: unsafe IP address: '%s'\n", asc);
+       if (!safe_inet_addr(asc, &addr)) {
+           debug(28, 0) ("decode_v4_addr: unsafe IP address: '%s'\n", asc);
            self_destruct();
        }
        break;
     case 1:                    /* a significant bits value for a mask */
        if (a1 >= 0 && a1 < 33) {
-           addr->s_addr = a1 ? htonl(0xfffffffful << (32 - a1)) : 0;
+           addr.s_addr = a1 ? htonl(0xfffffffful << (32 - a1)) : 0;
            break;
        }
     default:
-       debug(28, 0) ("decode_addr: Invalid IP address '%s'\n", asc);
+       debug(28, 0) ("decode_v4_addr: Invalid IP address '%s'\n", asc);
        return 0;               /* This is not valid address */
     }

+    sqinet_set_v4_inaddr(A, &addr);
     return 1;
 }

@@ -488,12 +490,19 @@
 #define SCAN_ACL4       "%[0123456789.]%c"

 static acl_ip_data *
-aclParseIpData(const char *t)
+aclParseIpData(const char *t, int af_family)
 {
     LOCAL_ARRAY(char, addr1, 256);
     LOCAL_ARRAY(char, addr2, 256);
     LOCAL_ARRAY(char, mask, 256);
+    LOCAL_ARRAY(char, buf, MAX_IPSTRLEN);
     acl_ip_data *q = memPoolAlloc(acl_ip_data_pool);
+    sqinet_init(&q->addr1);
+    sqinet_init(&q->addr2);
+    sqinet_init(&q->mask);
+    sqinet_set_family(&q->addr1, af_family);
+    sqinet_set_family(&q->addr2, af_family);
+    sqinet_set_family(&q->mask, af_family);
     acl_ip_data *r;
     acl_ip_data **Q;
     struct hostent *hp;
@@ -501,12 +510,12 @@
     char c;
     debug(28, 5) ("aclParseIpData: %s\n", t);
     if (!strcasecmp(t, "all")) {
-       q->addr1.s_addr = 0;
-       q->addr2.s_addr = 0;
-       q->mask.s_addr = 0;
+       sqinet_set_anyaddr(&q->addr1);
+       sqinet_set_anyaddr(&q->addr2);
+       sqinet_set_anyaddr(&q->mask);
        return q;
     }
-    SetNoAddr(&q->mask);        /* 255.255.255.255 */
+    sqinet_set_noaddr(&q->mask);        /* 255.255.255.255 / 
ffff:ffff:...:ffff */
     if (sscanf(t, SCAN_ACL1, addr1, addr2, mask) == 3) {
        (void) 0;
     } else if (sscanf(t, SCAN_ACL2, addr1, addr2, &c) == 2) {
@@ -532,11 +541,21 @@
        for (x = hp->h_addr_list; x != NULL && *x != NULL; x++) {
            if ((r = *Q) == NULL)
                r = *Q = memPoolAlloc(acl_ip_data_pool);
-           xmemcpy(&r->addr1.s_addr, *x, sizeof(r->addr1.s_addr));
-           r->addr2.s_addr = 0;
-           SetNoAddr(&r->mask); /* 255.255.255.255 */
+ /* XXX potentially double-init'ed here, thanks to this legacy evil C code! */
+           sqinet_init(&r->addr1);
+           sqinet_init(&r->addr2);
+           sqinet_init(&r->mask);
+           /*
+ * XXX at some point this should be modified to support v4 and v6 hosts,
+            * XXX with the correct address type for this particular IP list.
+            */
+           /* XXX is this cast even correct?! */
+           (void) sqinet_set_v4_inaddr(&r->addr1, (struct in_addr *) x);
+           sqinet_set_anyaddr(&r->addr2);       /* 0.0.0.0 */
+           sqinet_set_noaddr(&r->mask); /* 255.255.255.255, etc */
            Q = &r->next;
-           debug(28, 3) ("%s --> %s\n", addr1, inet_ntoa(r->addr1));
+           (void) sqinet_ntoa(&r->addr1, buf, sizeof(buf), SQATON_NONE);
+           debug(28, 3) ("%s --> %s\n", addr1, buf);
        }
        return q;
     } else {
@@ -545,7 +564,7 @@
        return NULL;
     }
     /* Decode addr1 */
-    if (!decode_addr(addr1, &q->addr1)) {
+    if (!decode_v4_addr(addr1, &q->addr1)) {
        debug(28, 0) ("%s line %d: %s\n",
            cfg_filename, config_lineno, config_input_line);
debug(28, 0) ("aclParseIpData: Ignoring invalid IP acl entry: unknown first address '%s'\n", addr1);
@@ -553,7 +572,7 @@
        return NULL;
     }
     /* Decode addr2 */
-    if (*addr2 && !decode_addr(addr2, &q->addr2)) {
+    if (*addr2 && !decode_v4_addr(addr2, &q->addr2)) {
        debug(28, 0) ("%s line %d: %s\n",
            cfg_filename, config_lineno, config_input_line);
debug(28, 0) ("aclParseIpData: Ignoring invalid IP acl entry: unknown second address '%s'\n", addr2);
@@ -561,18 +580,18 @@
        return NULL;
     }
     /* Decode mask */
-    if (*mask && !decode_addr(mask, &q->mask)) {
+    if (*mask && !decode_v4_addr(mask, &q->mask)) {
        debug(28, 0) ("%s line %d: %s\n",
            cfg_filename, config_lineno, config_input_line);
debug(28, 0) ("aclParseIpData: Ignoring invalid IP acl entry: unknown netmask '%s'\n", mask);
        safe_free(q);
        return NULL;
     }
-    if ((q->addr1.s_addr & q->mask.s_addr) != q->addr1.s_addr ||
-       (q->addr2.s_addr & q->mask.s_addr) != q->addr2.s_addr)
+ if (sqinet_host_is_netaddr(&q->addr1, &q->mask) || sqinet_host_is_netaddr(&q->addr2, &q->mask)) debug(28, 0) ("aclParseIpData: WARNING: Netmask masks away part of the specified IP in '%s'\n", t);
-    q->addr1.s_addr &= q->mask.s_addr;
-    q->addr2.s_addr &= q->mask.s_addr;
+    /* Store the masked version of the IP address */
+    sqinet_mask_addr(&q->addr1, &q->mask);
+    sqinet_mask_addr(&q->addr2, &q->mask);
     /* 1.2.3.4/255.255.255.0  --> 1.2.3.0 */
     return q;
 }
@@ -589,7 +608,8 @@
     acl_ip_data *q = NULL;
     while ((t = strtokFile())) {
        acl_ip_data *next;
-       for (q = aclParseIpData(t); q != NULL; q = next) {
+        /* XXX how do we determine whether the AF is INET or INET6? */
+       for (q = aclParseIpData(t, AF_INET); q != NULL; q = next) {
            next = q->next;
            *Top = splay_insert(q, *Top, aclIpNetworkCompare);
            if (splayLastResult == 0)
@@ -1341,6 +1361,7 @@
 {
     splayNode **Top = dataptr;
     acl_ip_data x;
+
     /*
      * aclIpAddrNetworkCompare() takes two acl_ip_data pointers as
      * arguments, so we must create a fake one for the client's IP
@@ -1350,13 +1371,23 @@
      * XXX Could eliminate these repetitive assignments with a
      * static structure.
      */
-    x.addr1 = c;
-    SetAnyAddr(&x.addr2);
-    SetNoAddr(&x.mask);
+    sqinet_init(&x.addr1);
+    sqinet_init(&x.addr2);
+    sqinet_init(&x.mask);
+
+    sqinet_set_v4_inaddr(&x.addr1, &c);
+    sqinet_set_family(&x.addr2, AF_INET);
+    sqinet_set_anyaddr(&x.addr2);
+    sqinet_set_family(&x.mask, AF_INET);
+    sqinet_set_noaddr(&x.mask);
+
     x.next = NULL;
     *Top = splay_splay(&x, *Top, aclIpAddrNetworkCompare);
     debug(28, 3) ("aclMatchIp: '%s' %s\n",
        inet_ntoa(c), splayLastResult ? "NOT found" : "found");
+    sqinet_done(&x.addr1);
+    sqinet_done(&x.addr2);
+    sqinet_done(&x.mask);
     return !splayLastResult;
 }

@@ -2556,6 +2587,9 @@
 static void
 aclFreeIpData(void *p)
 {
+    sqinet_done(&((acl_ip_data *) p)->addr1);
+    sqinet_done(&((acl_ip_data *) p)->addr2);
+    sqinet_done(&((acl_ip_data *) p)->mask);
     memPoolFree(acl_ip_data_pool, p);
 }

@@ -2779,17 +2813,20 @@
 static void
 aclIpDataToStr(const acl_ip_data * ip, char *buf, int len)
 {
-    char b1[20];
-    char b2[20];
-    char b3[20];
-    snprintf(b1, 20, "%s", inet_ntoa(ip->addr1));
-    if (! IsAnyAddr(&ip->addr2))
-       snprintf(b2, 20, "-%s", inet_ntoa(ip->addr2));
-    else
+    char b1[MAX_IPSTRLEN + 8];
+    char b2[MAX_IPSTRLEN + 8];
+    char b3[MAX_IPSTRLEN + 8];
+    (void) sqinet_ntoa(&ip->addr1, b1, sizeof(b1), SQATON_NONE);
+    if (! sqinet_is_anyaddr(&ip->addr2)) {
+        b2[0] = '-';
+ (void) sqinet_ntoa(&ip->addr2, b2 + 1, sizeof(b2) - 1, SQATON_NONE);
+    } else
        b2[0] = '\0';
-    if (! IsNoAddr(&ip->mask))
-       snprintf(b3, 20, "/%s", inet_ntoa(ip->mask));
-    else
+
+    if (! sqinet_is_noaddr(&ip->mask)) {
+        b3[0] = '/';
+        (void) sqinet_ntoa(&ip->mask, b3 + 1, sizeof(b3) - 1, SQATON_NONE);
+    } else
        b3[0] = '\0';
     snprintf(buf, len, "%s%s%s", b1, b2, b3);
 }
@@ -2804,26 +2841,18 @@
 static int
 aclIpNetworkCompare2(const acl_ip_data * p, const acl_ip_data * q)
 {
-    struct in_addr A = p->addr1;
-    const struct in_addr B = q->addr1;
-    const struct in_addr C = q->addr2;
+    sqaddr_t A;
     int rc = 0;
-    A.s_addr &= q->mask.s_addr; /* apply netmask */
-    if (C.s_addr == 0) {       /* single address check */
-       if (ntohl(A.s_addr) > ntohl(B.s_addr))
-           rc = 1;
-       else if (ntohl(A.s_addr) < ntohl(B.s_addr))
-           rc = -1;
-       else
-           rc = 0;
+
+    sqinet_init(&A);
+    sqinet_copy(&A, &p->addr1);
+    sqinet_mask_addr(&A, &q->mask); /* apply netmask */
+    if (sqinet_is_anyaddr(&q->addr2)) { /* single address check */
+        rc = sqinet_host_compare(&A, &q->addr1);
     } else {                   /* range address check */
-       if (ntohl(A.s_addr) > ntohl(C.s_addr))
-           rc = 1;
-       else if (ntohl(A.s_addr) < ntohl(B.s_addr))
-           rc = -1;
-       else
-           rc = 0;
-    }
+        rc = sqinet_range_compare(&A, &q->addr1, &q->addr2);
+    }
+    sqinet_done(&A);
     return rc;
 }

@@ -2848,12 +2877,12 @@
        ret = aclIpNetworkCompare2(n1, n2);
     }
     if (ret == 0) {
-       char buf_n1[60];
-       char buf_n2[60];
-       char buf_a[60];
-       aclIpDataToStr(n1, buf_n1, 60);
-       aclIpDataToStr(n2, buf_n2, 60);
-       aclIpDataToStr((acl_ip_data *) a, buf_a, 60);
+       char buf_n1[MAX_IPSTRLEN * 4];
+       char buf_n2[MAX_IPSTRLEN * 4];
+       char buf_a[MAX_IPSTRLEN * 4];
+       aclIpDataToStr(n1, buf_n1, sizeof(buf_n1));
+       aclIpDataToStr(n2, buf_n2, sizeof(buf_n2));
+       aclIpDataToStr((acl_ip_data *) a, buf_a, sizeof(buf_a));
        debug(28, 0) ("WARNING: '%s' is a subnetwork of "
            "'%s'\n", buf_n1, buf_n2);
        debug(28, 0) ("WARNING: because of this '%s' is ignored "
@@ -2904,15 +2933,23 @@
 static void
 aclDumpIpListWalkee(void *node, void *state)
 {
+    LOCAL_ARRAY(char, buf, MAX_IPSTRLEN);
     acl_ip_data *ip = node;
-    MemBuf mb;
     wordlist **W = state;
+    MemBuf mb;
+
     memBufDefInit(&mb);
-    memBufPrintf(&mb, "%s", inet_ntoa(ip->addr1));
-    if (! IsAnyAddr(&ip->addr2))
-       memBufPrintf(&mb, "-%s", inet_ntoa(ip->addr2));
-    if (! IsNoAddr(&ip->mask))
-       memBufPrintf(&mb, "/%s", inet_ntoa(ip->mask));
+
+    (void) sqinet_ntoa(&ip->addr1, buf, sizeof(buf), SQATON_NONE);
+    memBufPrintf(&mb, "%s", buf);
+    if (! sqinet_is_anyaddr(&ip->addr2)) {
+        (void) sqinet_ntoa(&ip->addr2, buf, sizeof(buf), SQATON_NONE);
+       memBufPrintf(&mb, "-%s", buf);
+    }
+    if (! sqinet_is_noaddr(&ip->mask)) {
+        (void) sqinet_ntoa(&ip->addr2, buf, sizeof(buf), SQATON_NONE);
+       memBufPrintf(&mb, "/%s", buf);
+    }
     wordlistAdd(W, mb.buf);
     memBufClean(&mb);
 }
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/structs.h      Thu Sep  2 18:24:55 2010
+++ /playpen/LUSCA_HEAD_ipv6/src/structs.h      Sat Sep  4 05:24:18 2010
@@ -62,10 +62,11 @@
     } flags;
 };

+/* XXX sockaddr_storage is 128 bytes each; this dramatically blows out the damned size of this! */
 struct _acl_ip_data {
-    struct in_addr addr1;      /* if addr2 non-zero then its a range */
-    struct in_addr addr2;
-    struct in_addr mask;
+    sqaddr_t addr1;    /* if addr2 non-zero then its a range */
+    sqaddr_t addr2;
+    sqaddr_t mask;
     acl_ip_data *next;         /* used for parsing, not for storing */
 };

--
You received this message because you are subscribed to the Google Groups 
"lusca-commit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/lusca-commit?hl=en.

Reply via email to