Mon Oct 25 23:57:33 CEST 1999 Modified Files in squid/src acl.c neighbors.c url.c Merged squid-2.2.STABLE5.aclDomainCompare.patch Duane's domain comparisation patch was not entirely correct after all. matchDomainName is sensitive to hosts vs domains so it should be defined in the same manner as it is used... (or the other way around). Apart from this it did return consistent results. Unfortunately this mismatch in argument order caused all domain comparisations to fail (FQDN comarisations matched). Also, the splay verifications was not updated to match the new semantics of .foo.com vs foo.com causing more warnings than neccesary and slightly incorrect error messages (to few dots). Sun Oct 24 22:38:36 CEST 1999 Merged a patch from Duane which he claims will fix those aclDomainCompare splay errors introduced by the change in 2.2.STABLE5.. Looks good this time. ----------------------------------------------------------------- Index: squid/src/acl.c diff -u squid/src/acl.c:1.1.1.36.2.7 squid/src/acl.c:1.1.1.36.2.8 --- squid/src/acl.c:1.1.1.36.2.7 Sun Oct 17 15:49:46 1999 +++ squid/src/acl.c Mon Oct 25 23:57:31 1999 @@ -1967,41 +1967,23 @@ static int aclDomainCompare(const void *a, const void *b) { - const char *d1 = a; - const char *d2 = b; - int l1; - int l2; -#if 0 /* .domain.com is all subdomains of domain.com, or - * aclHostDomainCompare needs to match this.. - */ - while ('.' == *d1) - d1++; - while ('.' == *d2) - d2++; -#endif - l1 = strlen(d1); - l2 = strlen(d2); - while (d1[--l1] == d2[--l2]) { - if ((l1 == 0) && (l2 == 0)) - return 0; /* d1 == d2 */ - if (0 == l1) { - if ('.' == d2[l2 - 1]) { - debug(28, 0) ("WARNING: %s is a subdomain of %s\n", d2, d1); - debug(28, 0) ("WARNING: This may break Splay tree searching\n"); - debug(28, 0) ("WARNING: You should remove '%s' from the ACL named '%s'\n", d2, AclMatchedName); - } - return -1; /* d1 < d2 */ - } - if (0 == l2) { - if ('.' == d1[l1 - 1]) { - debug(28, 0) ("WARNING: %s is a subdomain of %s\n", d1, d2); - debug(28, 0) ("WARNING: This may break Splay tree searching\n"); - debug(28, 0) ("WARNING: You should remove '%s' from the ACL named '%s'\n", d1, AclMatchedName); - } - return 1; /* d1 > d2 */ - } + const char *d1; + const char *d2; + int ret; + d1 = a; + d2 = b; + ret = matchDomainName(d1, d2); + if (ret != 0) { + d1 = b; + d2 = a; + ret = matchDomainName(d1, d2); + } + if (ret == 0) { + debug(28, 0) ("WARNING: '%s' is a subdomain of '%s'\n", d2, d1); + debug(28, 0) ("WARNING: because of this '%s' is ignored to keep Splay tree searching predictable\n", a); + debug(28, 0) ("WARNING: You should probably remove '%s' from the ACL named '%s'\n", d2, AclMatchedName); } - return (d1[l1] - d2[l2]); + return ret; } /* compare a host and a domain */ @@ -2011,27 +1993,7 @@ { const char *h = a; const char *d = b; - int l1; - int l2; - if (matchDomainName(d, h)) - return 0; - l1 = strlen(h); - l2 = strlen(d); - /* h != d */ - while (xtolower(h[--l1]) == xtolower(d[--l2])) { - if (l1 == 0) - return -1; /* domain(h) < d */ - if (l2 == 0) - return 1; /* domain(h) > d */ - } -#if 0 /* There isn't anything this special with '.' in aclDomainCompare...*/ - /* a '.' is a special case */ - if (h[l1] == '.') - return -1; /* domain(h) < d */ - if (d[l2] == '.') - return 1; /* domain(h) > d */ -#endif - return (xtolower(h[l1]) - xtolower(d[l2])); + return matchDomainName(d, h); } /* compare two network specs Index: squid/src/neighbors.c diff -u squid/src/neighbors.c:1.1.1.34.2.5 squid/src/neighbors.c:1.1.1.34.2.6 --- squid/src/neighbors.c:1.1.1.34.2.5 Sat Aug 7 19:59:24 1999 +++ squid/src/neighbors.c Mon Oct 25 23:57:32 1999 @@ -102,7 +102,7 @@ { const struct _domain_type *d = NULL; for (d = p->typelist; d; d = d->next) { - if (matchDomainName(d->domain, request->host)) + if (0 == matchDomainName(d->domain, request->host)) if (d->type != PEER_NONE) return d->type; } @@ -136,7 +136,7 @@ return do_ping; do_ping = 0; for (d = p->peer_domain; d; d = d->next) { - if (matchDomainName(d->domain, request->host)) { + if (0 == matchDomainName(d->domain, request->host)) { do_ping = d->do_ping; break; } Index: squid/src/url.c diff -u squid/src/url.c:1.1.1.27.2.3 squid/src/url.c:1.1.1.27.2.4 --- squid/src/url.c:1.1.1.27.2.3 Sun Aug 8 02:20:05 1999 +++ squid/src/url.c Mon Oct 25 23:57:32 1999 @@ -124,6 +124,29 @@ debug(23, 5) ("urlInitialize: Initializing...\n"); assert(sizeof(ProtocolStr) == (PROTO_MAX + 1) * sizeof(char *)); memset(&null_request_flags, '\0', sizeof(null_request_flags)); + /* + * These test that our matchDomainName() function works the + * way we expect it to. + */ + assert(0 == matchDomainName("foo.com", "foo.com")); + assert(0 == matchDomainName(".foo.com", "foo.com")); + assert(0 != matchDomainName("foo.com", ".foo.com")); + assert(0 == matchDomainName(".foo.com", ".foo.com")); + assert(0 == matchDomainName(".foo.com", "x.foo.com")); + assert(0 != matchDomainName("foo.com", "x.foo.com")); + assert(0 != matchDomainName("x.foo.com", "foo.com")); + assert(0 != matchDomainName("bar.com", "foo.com")); + assert(0 != matchDomainName("bar.com", ".foo.com")); + assert(0 != matchDomainName(".bar.com", "foo.com")); + assert(0 != matchDomainName(".bar.com", ".foo.com")); + assert(0 < matchDomainName("foo.com", "zzz.com")); + assert(0 > matchDomainName("foo.com", "aaa.com")); + assert(0 == matchDomainName("FOO.com", "foo.COM")); + assert(0 != matchDomainName("afoo.com", "foo.com")); + assert(0 != matchDomainName("foo.com", "afoo.com")); + assert(0 < matchDomainName("afoo.com", "bfoo.com")); + assert(0 > matchDomainName("bfoo.com", "afoo.com")); + /* more cases? */ } method_t @@ -363,21 +386,73 @@ return buf; } +/* + * matchDomainName() compares a hostname with a domainname according + * to the following rules: + * + * HOST DOMAIN MATCH? + * ------------- ------------- ------ + * foo.com foo.com YES + * .foo.com foo.com NO + * x.foo.com foo.com NO + * foo.com .foo.com YES + * .foo.com .foo.com YES + * x.foo.com .foo.com YES + * + * Return values: + * 0 means the host matches the domain + * >0 means the host is greater than the domain + * <0 means the host is less than the domain + */ + int -matchDomainName(const char *domain, const char *host) +matchDomainName(const char *d, const char *h) { - int offset; - if ((offset = strlen(host) - strlen(domain)) < 0) - return 0; /* host too short */ - if (strcasecmp(domain, host + offset) != 0) - return 0; /* no match at all */ - if (*domain == '.') - return 1; - if (offset == 0) - return 1; - if (*(host + offset - 1) == '.') - return 1; - return 0; + int dl; + int hl; + hl = strlen(h); + dl = strlen(d); + /* + * Start at the ends of the two strings and work towards the + * beginning. + */ + while (xtolower(h[--hl]) == xtolower(d[--dl])) { + if (hl == 0 && dl == 0) { + /* + * We made it all the way to the beginning of both + * strings without finding any difference. + */ + return 0; + } + if (0 == hl) { + /* + * The host string is shorter than the domain string. + * There is only one case when this can be a match. + * If the domain is just one character longer, and if + * that character is a leading '.' then we call it a + * match. + */ + if (1 == dl && '.' == d[0]) + return 0; + else + return -1; + } + if (0 == dl) { + /* + * The domain string is shorter than the host string. + * This is a match only if the first domain character + * is a leading '.'. + */ + if ('.' == d[0]) + return 0; + else + return 1; + } + } + /* + * We found different characters in the same position (from the end). + */ + return (xtolower(h[hl]) - xtolower(d[dl])); } int