From: Eduard Bagdasaryan Date: Wed, 9 Jul 2025 19:59:39 +0000 (+0000) Subject: Bug 5499: Remove support for src_as and dst_as ACLs (#2113) X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3cf3232ed9eb378d307dcf3e9c7a5a48c5b5d9c6;p=thirdparty%2Fsquid.git Bug 5499: Remove support for src_as and dst_as ACLs (#2113) Squid ACL initialization code calls asnCacheStart() and tries to connect to an ASN server. If the configuration requires a cache_peer, that connection fails because none of cache_peers are available an that time: WARNING: AS ... whois request failed Since ASN-based ACLs are essentially unused and properly fixing this bug requires significant effort work, we drop Autonomous System Numbers instead. Any rare use cases may implement an external ACL helper with similar functionality and more features. Also removed no longer necessary radix.{c,h} code, "asndb" cache manager report, and "asn" initiator value in transaction_initiator ACLs. --- diff --git a/CREDITS b/CREDITS index b505d98984..c2b4a9d37b 100644 --- a/CREDITS +++ b/CREDITS @@ -575,38 +575,6 @@ SOFTWARE. ============================================================================== -include/radix.h, -lib/radix.c: - - * Copyright (c) 1988, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - -============================================================================== - include/rfc2617.h, lib/rfc2617.c: @@ -760,13 +728,6 @@ lib/getopt.c: ============================================================================== -lib/radix.c: - - * Adapted from HTSUtils.c in CERN httpd 3.0 (http://info.cern.ch/httpd/) - * by Darren Hardy , November 1994. - -============================================================================== - lib/Splay.cc: * based on ftp://ftp.cs.cmu.edu/user/sleator/splaying/top-down-splay.c diff --git a/doc/Programming-Guide/03_MajorComponents.dox b/doc/Programming-Guide/03_MajorComponents.dox index eaaba92c1b..9f264328b9 100644 --- a/doc/Programming-Guide/03_MajorComponents.dox +++ b/doc/Programming-Guide/03_MajorComponents.dox @@ -180,14 +180,6 @@ TODO: decide what to do for comm_poll() since its either obsolete or uses other Common applications for this feature are extended access controls and local mirroring. File: redirect.c. -\section ASN Autonomous System Numbers -\par - Squid supports Autonomous System (AS) numbers as another - access control element. The routines in asn.c - query databases which map AS numbers into lists of CIDR - prefixes. These results are stored in a radix tree which - allows fast searching of the AS number for a given IP address. - \section ConfigurationFileParsing Configuration File Parsing \par The primary configuration file specification is in the file diff --git a/doc/debug-sections.txt b/doc/debug-sections.txt index 0c04378315..5503f082d8 100644 --- a/doc/debug-sections.txt +++ b/doc/debug-sections.txt @@ -99,8 +99,6 @@ section 49 SNMP support section 50 Log file handling section 51 Filedescriptor Functions section 52 URN Parsing -section 53 AS Number handling -section 53 Radix Tree data structure implementation section 54 Interprocess Communication section 54 Windows Interprocess Communication section 55 HTTP Header diff --git a/doc/release-notes/release-8.sgml.in b/doc/release-notes/release-8.sgml.in index c5b9ad74cb..4655df84a4 100644 --- a/doc/release-notes/release-8.sgml.in +++ b/doc/release-notes/release-8.sgml.in @@ -48,6 +48,11 @@ The Squid-@SQUID_RELEASE@ change history can be

-

No changed directives in this version. + acl + +

Removed support for src_as and dst_as ACLs. Based on + admin feedback and a history of serious implementation bugs that went + unnoticed for a long time, the two ACLs are considered to be essentially + unused. The corresponding Autonomous System Numbers (ASN) lookups can be + implemented (with more features) using external ACLs. Removing ASN lookup + support also removes ancient and neglected C code, improving Squid + security posture and simplifying development. Configurations using + src_as and dst_as ACL types are now rejected with FATAL + errors. + +

Removed support for asn initiator in + transaction_initiator ACLs. After removing support for + src_as and dst_as ACLs, Squid no longer initiates ASN + lookups. diff --git a/include/radix.h b/include/radix.h deleted file mode 100644 index 0f34029316..0000000000 --- a/include/radix.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 1996-2025 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID_INCLUDE_RADIX_H -#define SQUID_INCLUDE_RADIX_H - -/* - * Copyright (c) 1988, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)radix.h 8.2 (Berkeley) 10/31/94 - */ - -/* - * Radix search tree node layout. - */ - -struct squid_radix_node { - - struct squid_radix_mask *rn_mklist; /* list of masks contained in subtree */ - - struct squid_radix_node *rn_p; /* parent */ - short rn_b; /* bit offset; -1-index(netmask) */ - char rn_bmask; /* node: mask for bit test */ - unsigned char rn_flags; /* enumerated next */ -#define RNF_NORMAL 1 /* leaf contains normal route */ -#define RNF_ROOT 2 /* leaf is root leaf for tree */ -#define RNF_ACTIVE 4 /* This node is alive (for rtfree) */ - - union { - - struct { /* leaf only data: */ - char *rn_Key; /* object of search */ - char *rn_Mask; /* netmask, if present */ - - struct squid_radix_node *rn_Dupedkey; - } rn_leaf; - - struct { /* node only data: */ - int rn_Off; /* where to start compare */ - - struct squid_radix_node *rn_L; /* progeny */ - - struct squid_radix_node *rn_R; /* progeny */ - } rn_node; - } rn_u; -}; - -#define rn_key rn_u.rn_leaf.rn_Key -#define rn_mask rn_u.rn_leaf.rn_Mask - -/* - * Annotations to tree concerning potential routes applying to subtrees. - */ - -struct squid_radix_mask { - short rm_b; /* bit offset; -1-index(netmask) */ - char rm_unused; /* cf. rn_bmask */ - unsigned char rm_flags; /* cf. rn_flags */ - - struct squid_radix_mask *rm_mklist; /* more masks to try */ - union { - char *rmu_mask; /* the mask */ - - struct squid_radix_node *rmu_leaf; /* for normal routes */ - } rm_rmu; - int rm_refs; /* # of references to this struct */ -}; - -struct squid_radix_node_head { - - struct squid_radix_node *rnh_treetop; - int rnh_addrsize; /* permit, but not require fixed keys */ - int rnh_pktsize; /* permit, but not require fixed keys */ - - struct squid_radix_node *(*rnh_addaddr) /* add based on sockaddr */ - (void *v, void *mask, struct squid_radix_node_head * head, struct squid_radix_node nodes[]); - - struct squid_radix_node *(*rnh_addpkt) /* add based on packet hdr */ - (void *v, void *mask, struct squid_radix_node_head * head, struct squid_radix_node nodes[]); - - struct squid_radix_node *(*rnh_deladdr) /* remove based on sockaddr */ - (void *v, void *mask, struct squid_radix_node_head * head); - - struct squid_radix_node *(*rnh_delpkt) /* remove based on packet hdr */ - (void *v, void *mask, struct squid_radix_node_head * head); - - struct squid_radix_node *(*rnh_matchaddr) /* locate based on sockaddr */ - (void *v, struct squid_radix_node_head * head); - - struct squid_radix_node *(*rnh_lookup) /* locate based on sockaddr */ - - (void *v, void *mask, struct squid_radix_node_head * head); - - struct squid_radix_node *(*rnh_matchpkt) /* locate based on packet hdr */ - (void *v, struct squid_radix_node_head * head); - - int (*rnh_walktree) /* traverse tree */ - (struct squid_radix_node_head * head, int (*f) (struct squid_radix_node *, void *), void *w); - - struct squid_radix_node rnh_nodes[3]; /* empty tree for common case */ -}; - -SQUIDCEXTERN void squid_rn_init (void); - -SQUIDCEXTERN int squid_rn_inithead(struct squid_radix_node_head **, int); -SQUIDCEXTERN int squid_rn_refines(void *, void *); - -SQUIDCEXTERN int squid_rn_walktree(struct squid_radix_node_head *, int (*)(struct squid_radix_node *, void *), void *); - -SQUIDCEXTERN struct squid_radix_node *squid_rn_addmask(void *, int, int); - -SQUIDCEXTERN struct squid_radix_node *squid_rn_addroute(void *, void *, struct squid_radix_node_head *, struct squid_radix_node[2]); - -SQUIDCEXTERN struct squid_radix_node *squid_rn_delete(void *, void *, struct squid_radix_node_head *); - -SQUIDCEXTERN struct squid_radix_node *squid_rn_insert(void *, struct squid_radix_node_head *, int *, struct squid_radix_node[2]); - -SQUIDCEXTERN struct squid_radix_node *squid_rn_match(void *, struct squid_radix_node_head *); - -SQUIDCEXTERN struct squid_radix_node *squid_rn_newpair(void *, int, struct squid_radix_node[2]); - -SQUIDCEXTERN struct squid_radix_node *squid_rn_search(void *, struct squid_radix_node *); - -SQUIDCEXTERN struct squid_radix_node *squid_rn_search_m(void *, struct squid_radix_node *, void *); - -SQUIDCEXTERN struct squid_radix_node *squid_rn_lookup(void *, void *, struct squid_radix_node_head *); - -#endif /* SQUID_INCLUDE_RADIX_H */ - diff --git a/lib/Makefile.am b/lib/Makefile.am index a63cd36bcc..18659bdf32 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -53,7 +53,6 @@ libmisccontainers_la_SOURCES = \ libmiscutil_la_SOURCES = \ Splay.cc \ heap.c \ - radix.c \ util.cc TESTS += tests/testRFC1738 diff --git a/lib/radix.c b/lib/radix.c deleted file mode 100644 index a559f50d78..0000000000 --- a/lib/radix.c +++ /dev/null @@ -1,913 +0,0 @@ -/* - * Copyright (C) 1996-2025 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* - * Copyright (c) 1988, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)radix.c 8.4 (Berkeley) 11/2/94 - */ - -/* - * DEBUG: section 53 Radix Tree data structure implementation - */ - -#include "squid.h" -#include "radix.h" -#include "util.h" - -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_STDLIB_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#endif -#if HAVE_CTYPE_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#if HAVE_FCNTL_H -#include -#endif -#if HAVE_GRP_H -#include -#endif -#if HAVE_GNUMALLOC_H -#include -#elif HAVE_MALLOC_H -#include -#endif -#if HAVE_MEMORY_H -#include -#endif -#if HAVE_SYS_PARAM_H -#include -#endif -#if HAVE_ASSERT_H -#include -#endif - -int squid_max_keylen; -struct squid_radix_mask *squid_rn_mkfreelist; -struct squid_radix_node_head *squid_mask_rnhead; -static char *addmask_key; -static unsigned char normal_chars[] = {0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xFF}; -static char *rn_zeros, *rn_ones; - -/* aliases */ -#define rn_masktop (squid_mask_rnhead->rnh_treetop) -#define rn_dupedkey rn_u.rn_leaf.rn_Dupedkey -#define rn_off rn_u.rn_node.rn_Off -#define rn_l rn_u.rn_node.rn_L -#define rn_r rn_u.rn_node.rn_R -#define rm_mask rm_rmu.rmu_mask -#define rm_leaf rm_rmu.rmu_leaf /* extra field would make 32 bytes */ - -/* Helper macros */ -#define squid_R_Malloc(p, t, n) (p = (t) xmalloc((unsigned int)(n))) -#define squid_Free(p) xfree((char *)p) -#define squid_MKGet(m) {\ - if (squid_rn_mkfreelist) {\ - m = squid_rn_mkfreelist; \ - squid_rn_mkfreelist = (m)->rm_mklist; \ - } else \ - squid_R_Malloc(m, struct squid_radix_mask *, sizeof (*(m)));\ - } - -#define squid_MKFree(m) { (m)->rm_mklist = squid_rn_mkfreelist; squid_rn_mkfreelist = (m);} - -#ifndef min -#define min(x,y) ((x)<(y)? (x) : (y)) -#endif -/* - * The data structure for the keys is a radix tree with one way - * branching removed. The index rn_b at an internal node n represents a bit - * position to be tested. The tree is arranged so that all descendants - * of a node n have keys whose bits all agree up to position rn_b - 1. - * (We say the index of n is rn_b.) - * - * There is at least one descendant which has a one bit at position rn_b, - * and at least one with a zero there. - * - * A route is determined by a pair of key and mask. We require that the - * bit-wise logical and of the key and mask to be the key. - * We define the index of a route to associated with the mask to be - * the first bit number in the mask where 0 occurs (with bit number 0 - * representing the highest order bit). - * - * We say a mask is normal if every bit is 0, past the index of the mask. - * If a node n has a descendant (k, m) with index(m) == index(n) == rn_b, - * and m is a normal mask, then the route applies to every descendant of n. - * If the index(m) < rn_b, this implies the trailing last few bits of k - * before bit b are all 0, (and hence consequently true of every descendant - * of n), so the route applies to all descendants of the node as well. - * - * Similar logic shows that a non-normal mask m such that - * index(m) <= index(n) could potentially apply to many children of n. - * Thus, for each non-host route, we attach its mask to a list at an internal - * node as high in the tree as we can go. - * - * The present version of the code makes use of normal routes in short- - * circuiting an explicit mask and compare operation when testing whether - * a key satisfies a normal route, and also in remembering the unique leaf - * that governs a subtree. - */ - -struct squid_radix_node * -squid_rn_search(void *v_arg, struct squid_radix_node *head) { - register struct squid_radix_node *x; - register char *v; - - for (x = head, v = v_arg; x->rn_b >= 0;) { - if (x->rn_bmask & v[x->rn_off]) - x = x->rn_r; - else - x = x->rn_l; - } - return (x); -} - -struct squid_radix_node * -squid_rn_search_m(void *v_arg, struct squid_radix_node *head, void *m_arg) { - register struct squid_radix_node *x; - register char *v = v_arg, *m = m_arg; - - for (x = head; x->rn_b >= 0;) { - if ((x->rn_bmask & m[x->rn_off]) && - (x->rn_bmask & v[x->rn_off])) - x = x->rn_r; - else - x = x->rn_l; - } - return x; -} - -int -squid_rn_refines(void *m_arg, void *n_arg) -{ - register char *m = m_arg, *n = n_arg; - register char *lim, *lim2 = lim = n + *(u_char *) n; - int longer = (*(u_char *) n++) - (int) (*(u_char *) m++); - int masks_are_equal = 1; - - if (longer > 0) - lim -= longer; - while (n < lim) { - if (*n & ~(*m)) - return 0; - if (*n++ != *m++) - masks_are_equal = 0; - } - while (n < lim2) - if (*n++) - return 0; - if (masks_are_equal && (longer < 0)) - for (lim2 = m - longer; m < lim2;) - if (*m++) - return 1; - return (!masks_are_equal); -} - -struct squid_radix_node * -squid_rn_lookup(void *v_arg, void *m_arg, struct squid_radix_node_head *head) { - register struct squid_radix_node *x; - char *netmask = NULL; - - if (m_arg) { - if ((x = squid_rn_addmask(m_arg, 1, head->rnh_treetop->rn_off)) == 0) - return (0); - netmask = x->rn_key; - } - x = squid_rn_match(v_arg, head); - if (x && netmask) { - while (x && x->rn_mask != netmask) - x = x->rn_dupedkey; - } - return x; -} - -static int -rn_satsifies_leaf(char *trial, register struct squid_radix_node *leaf, int skip) -{ - register char *cp = trial, *cp2 = leaf->rn_key, *cp3 = leaf->rn_mask; - char *cplim; - int length = min(*(u_char *) cp, *(u_char *) cp2); - - if (cp3 == 0) - cp3 = rn_ones; - else - length = min(length, *(u_char *) cp3); - cplim = cp + length; - cp3 += skip; - cp2 += skip; - for (cp += skip; cp < cplim; cp++, cp2++, cp3++) - if ((*cp ^ *cp2) & *cp3) - return 0; - return 1; -} - -struct squid_radix_node * -squid_rn_match(void *v_arg, struct squid_radix_node_head *head) { - char *v = v_arg; - register struct squid_radix_node *t = head->rnh_treetop, *x; - register char *cp = v, *cp2; - char *cplim; - struct squid_radix_node *saved_t, *top = t; - int off = t->rn_off, vlen = *(u_char *) cp, matched_off; - register int test, b, rn_b; - - /* - * Open code squid_rn_search(v, top) to avoid overhead of extra - * subroutine call. - */ - for (; t->rn_b >= 0;) { - if (t->rn_bmask & cp[t->rn_off]) - t = t->rn_r; - else - t = t->rn_l; - } - /* - * See if we match exactly as a host destination - * or at least learn how many bits match, for normal mask finesse. - * - * It doesn't hurt us to limit how many bytes to check - * to the length of the mask, since if it matches we had a genuine - * match and the leaf we have is the most specific one anyway; - * if it didn't match with a shorter length it would fail - * with a long one. This wins big for class B&C netmasks which - * are probably the most common case... - */ - if (t->rn_mask) - vlen = *(u_char *) t->rn_mask; - cp += off; - cp2 = t->rn_key + off; - cplim = v + vlen; - for (; cp < cplim; cp++, cp2++) - if (*cp != *cp2) - goto on1; - /* - * This extra grot is in case we are explicitly asked - * to look up the default. Ugh! - */ - if ((t->rn_flags & RNF_ROOT) && t->rn_dupedkey) - t = t->rn_dupedkey; - return t; -on1: - test = (*cp ^ *cp2) & 0xff; /* find first bit that differs */ - for (b = 7; (test >>= 1) > 0;) - b--; - matched_off = cp - v; - b += matched_off << 3; - rn_b = -1 - b; - /* - * If there is a host route in a duped-key chain, it will be first. - */ - if ((saved_t = t)->rn_mask == 0) - t = t->rn_dupedkey; - for (; t; t = t->rn_dupedkey) - /* - * Even if we don't match exactly as a host, - * we may match if the leaf we wound up at is - * a route to a net. - */ - if (t->rn_flags & RNF_NORMAL) { - if (rn_b <= t->rn_b) - return t; - } else if (rn_satsifies_leaf(v, t, matched_off)) - return t; - t = saved_t; - /* start searching up the tree */ - do { - register struct squid_radix_mask *m; - t = t->rn_p; - if ((m = t->rn_mklist)) { - /* - * If non-contiguous masks ever become important - * we can restore the masking and open coding of - * the search and satisfaction test and put the - * calculation of "off" back before the "do". - */ - do { - if (m->rm_flags & RNF_NORMAL) { - if (rn_b <= m->rm_b) - return (m->rm_leaf); - } else { - off = min(t->rn_off, matched_off); - x = squid_rn_search_m(v, t, m->rm_mask); - while (x && x->rn_mask != m->rm_mask) - x = x->rn_dupedkey; - if (x && rn_satsifies_leaf(v, x, off)) - return x; - } - } while ((m = m->rm_mklist)); - } - } while (t != top); - return 0; -} - -struct squid_radix_node * -squid_rn_newpair(void *v, int b, struct squid_radix_node nodes[2]) { - register struct squid_radix_node *tt = nodes, *t = tt + 1; - t->rn_b = b; - t->rn_bmask = 0x80 >> (b & 7); - t->rn_l = tt; - t->rn_off = b >> 3; - tt->rn_b = -1; - tt->rn_key = (char *) v; - tt->rn_p = t; - tt->rn_flags = t->rn_flags = RNF_ACTIVE; - return t; -} - -struct squid_radix_node * -squid_rn_insert(void *v_arg, struct squid_radix_node_head *head, int *dupentry, struct squid_radix_node nodes[2]) { - char *v = v_arg; - struct squid_radix_node *top = head->rnh_treetop; - int head_off = top->rn_off, vlen = (int) *((u_char *) v); - register struct squid_radix_node *t = squid_rn_search(v_arg, top); - register char *cp = v + head_off; - register int b; - struct squid_radix_node *tt; - /* - * Find first bit at which v and t->rn_key differ - */ - { - register char *cp2 = t->rn_key + head_off; - register int cmp_res; - char *cplim = v + vlen; - - while (cp < cplim) - if (*cp2++ != *cp++) - goto on1; - *dupentry = 1; - return t; -on1: - *dupentry = 0; - cmp_res = (cp[-1] ^ cp2[-1]) & 0xff; - for (b = (cp - v) << 3; cmp_res; b--) - cmp_res >>= 1; - } - { - register struct squid_radix_node *p, *x = top; - cp = v; - do { - p = x; - if (cp[x->rn_off] & x->rn_bmask) - x = x->rn_r; - else - x = x->rn_l; - } while (b > (unsigned) x->rn_b); /* x->rn_b < b && x->rn_b >= 0 */ - t = squid_rn_newpair(v_arg, b, nodes); - tt = t->rn_l; - if ((cp[p->rn_off] & p->rn_bmask) == 0) - p->rn_l = t; - else - p->rn_r = t; - x->rn_p = t; - t->rn_p = p; /* frees x, p as temp vars below */ - if ((cp[t->rn_off] & t->rn_bmask) == 0) { - t->rn_r = x; - } else { - t->rn_r = tt; - t->rn_l = x; - } - } - return (tt); -} - -struct squid_radix_node * -squid_rn_addmask(void *n_arg, int search, int skip) { - char *netmask = (char *) n_arg; - register struct squid_radix_node *x; - register char *cp, *cplim; - register int b = 0, mlen, j; - int maskduplicated, m0, isnormal; - struct squid_radix_node *saved_x; - static int last_zeroed = 0; - - if ((mlen = *(u_char *) netmask) > squid_max_keylen) - mlen = squid_max_keylen; - if (skip == 0) - skip = 1; - if (mlen <= skip) - return (squid_mask_rnhead->rnh_nodes); - if (skip > 1) - memcpy(addmask_key + 1, rn_ones + 1, skip - 1); - if ((m0 = mlen) > skip) - memcpy(addmask_key + skip, netmask + skip, mlen - skip); - /* - * Trim trailing zeroes. - */ - for (cp = addmask_key + mlen; (cp > addmask_key) && cp[-1] == 0;) - cp--; - mlen = cp - addmask_key; - if (mlen <= skip) { - if (m0 >= last_zeroed) - last_zeroed = mlen; - return (squid_mask_rnhead->rnh_nodes); - } - if (m0 < last_zeroed) - memset(addmask_key + m0, '\0', last_zeroed - m0); - *addmask_key = last_zeroed = mlen; - x = squid_rn_search(addmask_key, rn_masktop); - if (memcmp(addmask_key, x->rn_key, mlen) != 0) - x = 0; - if (x || search) - return (x); - squid_R_Malloc(x, struct squid_radix_node *, squid_max_keylen + 2 * sizeof(*x)); - if ((saved_x = x) == 0) - return (0); - memset(x, '\0', squid_max_keylen + 2 * sizeof(*x)); - netmask = cp = (char *) (x + 2); - memcpy(cp, addmask_key, mlen); - x = squid_rn_insert(cp, squid_mask_rnhead, &maskduplicated, x); - if (maskduplicated) { - fprintf(stderr, "squid_rn_addmask: mask impossibly already in tree"); - squid_Free(saved_x); - return (x); - } - /* - * Calculate index of mask, and check for normalcy. - */ - cplim = netmask + mlen; - isnormal = 1; - for (cp = netmask + skip; (cp < cplim) && *(u_char *) cp == 0xff;) - cp++; - if (cp != cplim) { - for (j = 0x80; (j & *cp) != 0; j >>= 1) - b++; - if (*cp != normal_chars[b] || cp != (cplim - 1)) - isnormal = 0; - } - b += (cp - netmask) << 3; - x->rn_b = -1 - b; - if (isnormal) - x->rn_flags |= RNF_NORMAL; - return (x); -} - -static int /* XXX: arbitrary ordering for non-contiguous masks */ -rn_lexobetter(void *m_arg, void *n_arg) -{ - register u_char *mp = m_arg, *np = n_arg, *lim; - - if (*mp > *np) - return 1; /* not really, but need to check longer one first */ - if (*mp == *np) - for (lim = mp + *mp; mp < lim;) - if (*mp++ > *np++) - return 1; - return 0; -} - -static struct squid_radix_mask * -rn_new_radix_mask(struct squid_radix_node *tt, struct squid_radix_mask *next) { - register struct squid_radix_mask *m; - - squid_MKGet(m); - if (m == 0) { - fprintf(stderr, "Mask for route not entered\n"); - return (0); - } - memset(m, '\0', sizeof *m); - m->rm_b = tt->rn_b; - m->rm_flags = tt->rn_flags; - if (tt->rn_flags & RNF_NORMAL) - m->rm_leaf = tt; - else - m->rm_mask = tt->rn_mask; - m->rm_mklist = next; - tt->rn_mklist = m; - return m; -} - -struct squid_radix_node * -squid_rn_addroute(void *v_arg, void *n_arg, struct squid_radix_node_head *head, struct squid_radix_node treenodes[2]) { - char *v = (char *) v_arg, *netmask = (char *) n_arg; - register struct squid_radix_node *t, *x = NULL, *tt; - struct squid_radix_node *saved_tt, *top = head->rnh_treetop; - short b = 0, b_leaf = 0; - int keyduplicated; - char *mmask; - struct squid_radix_mask *m, **mp; - - /* - * In dealing with non-contiguous masks, there may be - * many different routes which have the same mask. - * We will find it useful to have a unique pointer to - * the mask to speed avoiding duplicate references at - * nodes and possibly save time in calculating indices. - */ - if (netmask) { - if ((x = squid_rn_addmask(netmask, 0, top->rn_off)) == 0) - return (0); - b_leaf = x->rn_b; - b = -1 - x->rn_b; - netmask = x->rn_key; - } - /* - * Deal with duplicated keys: attach node to previous instance - */ - saved_tt = tt = squid_rn_insert(v, head, &keyduplicated, treenodes); - if (keyduplicated) { - for (t = tt; tt; t = tt, tt = tt->rn_dupedkey) { - if (tt->rn_mask == netmask) - return (0); - if (netmask == 0 || - (tt->rn_mask && - ((b_leaf < tt->rn_b) || /* index(netmask) > node */ - squid_rn_refines(netmask, tt->rn_mask) || - rn_lexobetter(netmask, tt->rn_mask)))) - break; - } - /* - * If the mask is not duplicated, we wouldn't - * find it among possible duplicate key entries - * anyway, so the above test doesn't hurt. - * - * We sort the masks for a duplicated key the same way as - * in a masklist -- most specific to least specific. - * This may require the unfortunate nuisance of relocating - * the head of the list. - */ - if (tt == saved_tt) { - struct squid_radix_node *xx = x; - /* link in at head of list */ - tt = treenodes; - tt->rn_dupedkey = t; - tt->rn_flags = t->rn_flags; - tt->rn_p = x = t->rn_p; - if (x->rn_l == t) - x->rn_l = tt; - else - x->rn_r = tt; - saved_tt = tt; - x = xx; - } else { - tt = treenodes; - tt->rn_dupedkey = t->rn_dupedkey; - t->rn_dupedkey = tt; - } - tt->rn_key = (char *) v; - tt->rn_b = -1; - tt->rn_flags = RNF_ACTIVE; - } - /* - * Put mask in tree. - */ - if (netmask) { - tt->rn_mask = netmask; - tt->rn_b = x->rn_b; - tt->rn_flags |= x->rn_flags & RNF_NORMAL; - } - t = saved_tt->rn_p; - if (keyduplicated) - goto on2; - b_leaf = -1 - t->rn_b; - if (t->rn_r == saved_tt) - x = t->rn_l; - else - x = t->rn_r; - /* Promote general routes from below */ - if (x->rn_b < 0) { - for (mp = &t->rn_mklist; x; x = x->rn_dupedkey) - if (x->rn_mask && (x->rn_b >= b_leaf) && x->rn_mklist == 0) { - if ((*mp = m = rn_new_radix_mask(x, 0))) - mp = &m->rm_mklist; - } - } else if (x->rn_mklist) { - /* - * Skip over masks whose index is > that of new node - */ - for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist) - if (m->rm_b >= b_leaf) - break; - t->rn_mklist = m; - *mp = 0; - } -on2: - /* Add new route to highest possible ancestor's list */ - if ((netmask == 0) || (b > t->rn_b)) - return tt; /* can't lift at all */ - b_leaf = tt->rn_b; - do { - x = t; - t = t->rn_p; - } while (b <= t->rn_b && x != top); - /* - * Search through routes associated with node to - * insert new route according to index. - * Need same criteria as when sorting dupedkeys to avoid - * double loop on deletion. - */ - for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist) { - if (m->rm_b < b_leaf) - continue; - if (m->rm_b > b_leaf) - break; - if (m->rm_flags & RNF_NORMAL) { - mmask = m->rm_leaf->rn_mask; - if (tt->rn_flags & RNF_NORMAL) { - fprintf(stderr, - "Non-unique normal route, mask not entered"); - return tt; - } - } else - mmask = m->rm_mask; - if (mmask == netmask) { - m->rm_refs++; - tt->rn_mklist = m; - return tt; - } - if (squid_rn_refines(netmask, mmask) || rn_lexobetter(netmask, mmask)) - break; - } - *mp = rn_new_radix_mask(tt, *mp); - return tt; -} - -struct squid_radix_node * -squid_rn_delete(void *v_arg, void *netmask_arg, struct squid_radix_node_head *head) { - register struct squid_radix_node *t, *p, *x, *tt; - struct squid_radix_mask *m, *saved_m, **mp; - struct squid_radix_node *dupedkey, *saved_tt, *top; - char *v, *netmask; - int b, head_off, vlen; - - v = v_arg; - netmask = netmask_arg; - x = head->rnh_treetop; - tt = squid_rn_search(v, x); - head_off = x->rn_off; - vlen = *(u_char *) v; - saved_tt = tt; - top = x; - if (tt == 0 || - memcmp(v + head_off, tt->rn_key + head_off, vlen - head_off)) - return (0); - /* - * Delete our route from mask lists. - */ - if (netmask) { - if ((x = squid_rn_addmask(netmask, 1, head_off)) == 0) - return (0); - netmask = x->rn_key; - while (tt->rn_mask != netmask) - if ((tt = tt->rn_dupedkey) == 0) - return (0); - } - if (tt->rn_mask == 0 || (saved_m = m = tt->rn_mklist) == 0) - goto on1; - if (tt->rn_flags & RNF_NORMAL) { - if (m->rm_leaf != tt || m->rm_refs > 0) { - fprintf(stderr, "squid_rn_delete: inconsistent annotation\n"); - return 0; /* dangling ref could cause disaster */ - } - } else { - if (m->rm_mask != tt->rn_mask) { - fprintf(stderr, "squid_rn_delete: inconsistent annotation\n"); - goto on1; - } - if (--m->rm_refs >= 0) - goto on1; - } - b = -1 - tt->rn_b; - t = saved_tt->rn_p; - if (b > t->rn_b) - goto on1; /* Wasn't lifted at all */ - do { - x = t; - t = t->rn_p; - } while (b <= t->rn_b && x != top); - for (mp = &x->rn_mklist; (m = *mp); mp = &m->rm_mklist) - if (m == saved_m) { - *mp = m->rm_mklist; - squid_MKFree(m); - break; - } - if (m == 0) { - fprintf(stderr, "squid_rn_delete: couldn't find our annotation\n"); - if (tt->rn_flags & RNF_NORMAL) - return (0); /* Dangling ref to us */ - } -on1: - /* - * Eliminate us from tree - */ - if (tt->rn_flags & RNF_ROOT) - return (0); - t = tt->rn_p; - if ((dupedkey = saved_tt->rn_dupedkey)) { - if (tt == saved_tt) { - x = dupedkey; - x->rn_p = t; - if (t->rn_l == tt) - t->rn_l = x; - else - t->rn_r = x; - } else { - for (x = p = saved_tt; p && p->rn_dupedkey != tt;) - p = p->rn_dupedkey; - if (p) - p->rn_dupedkey = tt->rn_dupedkey; - else - fprintf(stderr, "squid_rn_delete: couldn't find us\n"); - } - t = tt + 1; - if (t->rn_flags & RNF_ACTIVE) { - *++x = *t; - p = t->rn_p; - if (p->rn_l == t) - p->rn_l = x; - else - p->rn_r = x; - x->rn_l->rn_p = x; - x->rn_r->rn_p = x; - } - goto out; - } - if (t->rn_l == tt) - x = t->rn_r; - else - x = t->rn_l; - p = t->rn_p; - if (p->rn_r == t) - p->rn_r = x; - else - p->rn_l = x; - x->rn_p = p; - /* - * Demote routes attached to us. - */ - if (t->rn_mklist) { - if (x->rn_b >= 0) { - for (mp = &x->rn_mklist; (m = *mp);) - mp = &m->rm_mklist; - *mp = t->rn_mklist; - } else { - /* If there are any key,mask pairs in a sibling - * duped-key chain, some subset will appear sorted - * in the same order attached to our mklist */ - for (m = t->rn_mklist; m && x; x = x->rn_dupedkey) - if (m == x->rn_mklist) { - struct squid_radix_mask *mm = m->rm_mklist; - x->rn_mklist = 0; - if (--(m->rm_refs) < 0) - squid_MKFree(m); - m = mm; - } - assert(m == NULL); - } - } - /* - * We may be holding an active internal node in the tree. - */ - x = tt + 1; - if (t != x) { - *t = *x; - t->rn_l->rn_p = t; - t->rn_r->rn_p = t; - p = x->rn_p; - if (p->rn_l == x) - p->rn_l = t; - else - p->rn_r = t; - } -out: - tt->rn_flags &= ~RNF_ACTIVE; - tt[1].rn_flags &= ~RNF_ACTIVE; - return (tt); -} - -int -squid_rn_walktree(struct squid_radix_node_head *h, int (*f) (struct squid_radix_node *, void *), void *w) -{ - int error; - struct squid_radix_node *base, *next; - register struct squid_radix_node *rn = h->rnh_treetop; - /* - * This gets complicated because we may delete the node - * while applying the function f to it, so we need to calculate - * the successor node in advance. - */ - /* First time through node, go left */ - while (rn->rn_b >= 0) - rn = rn->rn_l; - for (;;) { - base = rn; - /* If at right child go back up, otherwise, go right */ - while (rn->rn_p->rn_r == rn && (rn->rn_flags & RNF_ROOT) == 0) - rn = rn->rn_p; - /* Find the next *leaf* since next node might vanish, too */ - for (rn = rn->rn_p->rn_r; rn->rn_b >= 0;) - rn = rn->rn_l; - next = rn; - /* Process leaves */ - while ((rn = base)) { - base = rn->rn_dupedkey; - if (!(rn->rn_flags & RNF_ROOT) && (error = (*f) (rn, w))) - return (error); - } - rn = next; - if (rn->rn_flags & RNF_ROOT) - return (0); - } - /* NOTREACHED */ -} - -int -squid_rn_inithead(struct squid_radix_node_head **head, int off) -{ - register struct squid_radix_node_head *rnh; - register struct squid_radix_node *t, *tt, *ttt; - if (*head) - return (1); - squid_R_Malloc(rnh, struct squid_radix_node_head *, sizeof(*rnh)); - if (rnh == 0) - return (0); - memset(rnh, '\0', sizeof(*rnh)); - *head = rnh; - t = squid_rn_newpair(rn_zeros, off, rnh->rnh_nodes); - ttt = rnh->rnh_nodes + 2; - t->rn_r = ttt; - t->rn_p = t; - tt = t->rn_l; - tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE; - tt->rn_b = -1 - off; - *ttt = *tt; - ttt->rn_key = rn_ones; - rnh->rnh_addaddr = squid_rn_addroute; - rnh->rnh_deladdr = squid_rn_delete; - rnh->rnh_matchaddr = squid_rn_match; - rnh->rnh_lookup = squid_rn_lookup; - rnh->rnh_walktree = squid_rn_walktree; - rnh->rnh_treetop = t; - return (1); -} - -void -squid_rn_init(void) -{ - char *cp, *cplim; -#ifdef KERNEL - struct domain *dom; - - for (dom = domains; dom; dom = dom->dom_next) - if (dom->dom_maxrtkey > squid_max_keylen) - squid_max_keylen = dom->dom_maxrtkey; -#endif - if (squid_max_keylen == 0) { - fprintf(stderr, - "squid_rn_init: radix functions require squid_max_keylen be set\n"); - return; - } - squid_R_Malloc(rn_zeros, char *, 3 * squid_max_keylen); - if (rn_zeros == NULL) { - fprintf(stderr, "squid_rn_init failed.\n"); - exit(-1); - } - memset(rn_zeros, '\0', 3 * squid_max_keylen); - rn_ones = cp = rn_zeros + squid_max_keylen; - addmask_key = cplim = rn_ones + squid_max_keylen; - while (cp < cplim) - *cp++ = -1; - if (squid_rn_inithead(&squid_mask_rnhead, 0) == 0) { - fprintf(stderr, "rn_init2 failed.\n"); - exit(-1); - } -} - diff --git a/src/AclRegs.cc b/src/AclRegs.cc index 53da802b9e..18f54c19bf 100644 --- a/src/AclRegs.cc +++ b/src/AclRegs.cc @@ -25,11 +25,9 @@ #include "acl/AtStep.h" #include "acl/AtStepData.h" #endif -#include "acl/Asn.h" #include "acl/Checklist.h" #include "acl/ConnectionsEncrypted.h" #include "acl/Data.h" -#include "acl/DestinationAsn.h" #include "acl/DestinationDomain.h" #include "acl/DestinationIp.h" #include "acl/DomainData.h" @@ -70,7 +68,6 @@ #include "acl/ReplyMimeType.h" #include "acl/RequestHeaderStrategy.h" #include "acl/RequestMimeType.h" -#include "acl/SourceAsn.h" #include "acl/SourceDomain.h" #include "acl/SourceIp.h" #include "acl/SquidError.h" @@ -198,8 +195,6 @@ Acl::Init() RegisterMaker("any-of", [](TypeName)->Node* { return new AnyOf; }); // XXX: Add name parameter to ctor RegisterMaker("random", [](TypeName name)->Node* { return new ACLRandom(name); }); RegisterMaker("time", [](TypeName name)->Node* { return new FinalizedParameterizedNode(name, new ACLTimeData); }); - RegisterMaker("src_as", [](TypeName name)->Node* { return new FinalizedParameterizedNode(name, new ACLASN); }); - RegisterMaker("dst_as", [](TypeName name)->Node* { return new FinalizedParameterizedNode(name, new ACLASN); }); RegisterMaker("browser", [](TypeName name)->Node* { return new FinalizedParameterizedNode >(name, new ACLRegexData); }); RegisterMaker("dstdomain", [](TypeName name)->Node* { return new FinalizedParameterizedNode(name, new ACLDomainData); }); diff --git a/src/XactionInitiator.cc b/src/XactionInitiator.cc index 722dfcdd6a..900671b209 100644 --- a/src/XactionInitiator.cc +++ b/src/XactionInitiator.cc @@ -27,7 +27,6 @@ XactionInitiator::ParseInitiators(const char *name) {"htcp", initHtcp}, {"icp", initIcp}, {"icmp", initIcmp}, - {"asn", initAsn}, {"ipc", initIpc}, {"adaptation", initAdaptation}, {"icon", initIcon}, diff --git a/src/XactionInitiator.h b/src/XactionInitiator.h index 253a09abce..4a36e00477 100644 --- a/src/XactionInitiator.h +++ b/src/XactionInitiator.h @@ -22,7 +22,6 @@ public: initHtcp = 1<< 5, ///< HTCP client initIcp = 1 << 6, ///< the ICP/neighbors subsystem initIcmp = 1 << 7, ///< the ICMP RTT database (NetDB) neighbors exchange subsystem - initAsn = 1 << 8, ///< the ASN db subsystem initIpc = 1 << 9, ///< the IPC subsystem initAdaptation = 1 << 10, ///< ICAP/ECAP requests generated by Squid initIcon = 1 << 11, ///< internal icons diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc deleted file mode 100644 index 750b73a87d..0000000000 --- a/src/acl/Asn.cc +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Copyright (C) 1996-2025 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* DEBUG: section 53 AS Number handling */ - -#include "squid.h" -#include "acl/Acl.h" -#include "acl/Asn.h" -#include "acl/DestinationAsn.h" -#include "acl/DestinationIp.h" -#include "acl/FilledChecklist.h" -#include "acl/SourceAsn.h" -#include "base/CharacterSet.h" -#include "FwdState.h" -#include "HttpReply.h" -#include "HttpRequest.h" -#include "ipcache.h" -#include "MasterXaction.h" -#include "mgr/Registration.h" -#include "parser/Tokenizer.h" -#include "radix.h" -#include "RequestFlags.h" -#include "sbuf/SBuf.h" -#include "SquidConfig.h" -#include "Store.h" -#include "StoreClient.h" - -/* BEGIN of definitions for radix tree entries */ - -/* 32/128 bits address in memory with length */ -class m_ADDR -{ -public: - uint8_t len; - Ip::Address addr; - - m_ADDR() : len(sizeof(Ip::Address)) {}; -}; - -/* END of definitions for radix tree entries */ - -/* Head for ip to asn radix tree */ - -struct squid_radix_node_head *AS_tree_head; - -/* explicit instantiation required for some systems */ - -/// \cond AUTODOCS_IGNORE -template cbdata_type CbDataList::CBDATA_CbDataList; -/// \endcond - -/** - * Structure for as number information. it could be simply - * a list but it's coded as a structure for future - * enhancements (e.g. expires) - */ -struct as_info { - CbDataList *as_number; - time_t expires; /* NOTUSED */ -}; - -class ASState -{ - CBDATA_CLASS(ASState); - -public: - ASState() = default; - - ~ASState() { - if (entry) { - debugs(53, 3, entry->url()); - storeUnregister(sc, entry, this); - entry->unlock("~ASState"); - } - } - -public: - StoreEntry *entry = nullptr; - store_client *sc = nullptr; - HttpRequest::Pointer request; - int as_number = 0; - - /// for receiving a WHOIS reply body from Store and interpreting it - Store::ParsingBuffer parsingBuffer; -}; - -CBDATA_CLASS_INIT(ASState); - -/** entry into the radix tree */ -struct rtentry_t { - struct squid_radix_node e_nodes[2]; - as_info *e_info; - m_ADDR e_addr; - m_ADDR e_mask; -}; - -static int asnAddNet(const SBuf &, int); - -static void asnCacheStart(int as); - -static STCB asHandleReply; - -#if defined(__cplusplus) -extern "C" { -#endif - -static int destroyRadixNode(struct squid_radix_node *rn, void *w); -static int printRadixNode(struct squid_radix_node *rn, void *sentry); - -#if defined(__cplusplus) -} -#endif - -static void destroyRadixNodeInfo(as_info *); - -static OBJH asnStats; - -/* PUBLIC */ - -int -asnMatchIp(CbDataList *data, Ip::Address &addr) -{ - struct squid_radix_node *rn; - as_info *e; - m_ADDR m_addr; - CbDataList *a = nullptr; - CbDataList *b = nullptr; - - debugs(53, 3, "asnMatchIp: Called for " << addr ); - - if (AS_tree_head == nullptr) - return 0; - - if (addr.isNoAddr()) - return 0; - - if (addr.isAnyAddr()) - return 0; - - m_addr.addr = addr; - - rn = squid_rn_match(&m_addr, AS_tree_head); - - if (rn == nullptr) { - debugs(53, 3, "asnMatchIp: Address not in as db."); - return 0; - } - - debugs(53, 3, "asnMatchIp: Found in db!"); - e = ((rtentry_t *) rn)->e_info; - assert(e); - - for (a = data; a; a = a->next) - for (b = e->as_number; b; b = b->next) - if (a->element == b->element) { - debugs(53, 5, "asnMatchIp: Found a match!"); - return 1; - } - - debugs(53, 5, "asnMatchIp: AS not in as db."); - return 0; -} - -void -ACLASN::prepareForUse() -{ - for (CbDataList *i = data; i; i = i-> - next) - asnCacheStart(i->element); -} - -static void -asnRegisterWithCacheManager(void) -{ - Mgr::RegisterAction("asndb", "AS Number Database", asnStats, 0, 1); -} - -/* initialize the radix tree structure */ - -SQUIDCEXTERN int squid_max_keylen; /* yuck.. this is in lib/radix.c */ - -void -asnInit(void) -{ - static bool inited = false; - squid_max_keylen = 40; - - if (!inited) { - inited = true; - squid_rn_init(); - } - - squid_rn_inithead(&AS_tree_head, 8); - - asnRegisterWithCacheManager(); -} - -void -asnFreeMemory(void) -{ - squid_rn_walktree(AS_tree_head, destroyRadixNode, AS_tree_head); - - destroyRadixNode((struct squid_radix_node *) nullptr, (void *) AS_tree_head); -} - -static void -asnStats(StoreEntry * sentry) -{ - storeAppendPrintf(sentry, "Address \tAS Numbers\n"); - squid_rn_walktree(AS_tree_head, printRadixNode, sentry); -} - -/* PRIVATE */ - -static void -asnCacheStart(int as) -{ - AnyP::Uri whoisUrl(AnyP::PROTO_WHOIS); - whoisUrl.host(Config.as_whois_server); - whoisUrl.defaultPort(); - - SBuf asPath("/!gAS"); - asPath.appendf("%d", as); - whoisUrl.path(asPath); - - debugs(53, 3, "AS " << as); - ASState *asState = new ASState; - asState->as_number = as; - const auto mx = MasterXaction::MakePortless(); - asState->request = new HttpRequest(mx); - asState->request->url = whoisUrl; - asState->request->method = Http::METHOD_GET; - - // XXX: performance regression, c_str() reallocates - const auto asres = xstrdup(whoisUrl.absolute().c_str()); - - // XXX: Missing a hittingRequiresCollapsing() && startCollapsingOn() check. - auto e = storeGetPublic(asres, Http::METHOD_GET); - if (!e) { - e = storeCreateEntry(asres, asres, RequestFlags(), Http::METHOD_GET); - asState->sc = storeClientListAdd(e, asState); - FwdState::fwdStart(Comm::ConnectionPointer(), e, asState->request.getRaw()); - } else { - e->lock("Asn"); - asState->sc = storeClientListAdd(e, asState); - } - xfree(asres); - - asState->entry = e; - storeClientCopy(asState->sc, e, asState->parsingBuffer.makeInitialSpace(), asHandleReply, asState); -} - -static void -asHandleReply(void *data, StoreIOBuffer result) -{ - ASState *asState = (ASState *)data; - StoreEntry *e = asState->entry; - - debugs(53, 3, result << " for " << asState->as_number << " with " << *e); - - /* First figure out whether we should abort the request */ - - if (EBIT_TEST(e->flags, ENTRY_ABORTED)) { - delete asState; - return; - } - - if (result.flags.error) { - debugs(53, DBG_IMPORTANT, "ERROR: asHandleReply: Called with Error set and size=" << (unsigned int) result.length); - delete asState; - return; - } else if (e->mem().baseReply().sline.status() != Http::scOkay) { - debugs(53, DBG_IMPORTANT, "WARNING: AS " << asState->as_number << " whois request failed"); - delete asState; - return; - } - - asState->parsingBuffer.appended(result.data, result.length); - Parser::Tokenizer tok(SBuf(asState->parsingBuffer.content().data, asState->parsingBuffer.contentSize())); - SBuf address; - // Word delimiters in WHOIS ASN replies. RFC 3912 mentions SP, CR, and LF. - // Others are added to mimic an earlier isspace()-based implementation. - static const auto WhoisSpaces = CharacterSet("ASCII_spaces", " \f\r\n\t\v"); - while (tok.token(address, WhoisSpaces)) { - (void)asnAddNet(address, asState->as_number); - } - asState->parsingBuffer.consume(tok.parsedSize()); - const auto leftoverBytes = asState->parsingBuffer.contentSize(); - - if (asState->sc->atEof()) { - if (leftoverBytes) - debugs(53, 2, "WHOIS: Discarding the last " << leftoverBytes << " received bytes of a truncated AS response"); - delete asState; - return; - } - - const auto remainingSpace = asState->parsingBuffer.space().positionAt(result.offset + result.length); - - if (!remainingSpace.length) { - Assure(leftoverBytes); - debugs(53, DBG_IMPORTANT, "WARNING: Ignoring the tail of a WHOIS AS response" << - " with an unparsable section of " << leftoverBytes << - " bytes ending at offset " << remainingSpace.offset); - delete asState; - return; - } - - const decltype(StoreIOBuffer::offset) stillReasonableOffset = 100000; // an arbitrary limit in bytes - if (remainingSpace.offset > stillReasonableOffset) { - // stop suspicious accumulation of parsed addresses and/or work - debugs(53, DBG_IMPORTANT, "WARNING: Ignoring the tail of a suspiciously large WHOIS AS response" << - " exceeding " << stillReasonableOffset << " bytes"); - delete asState; - return; - } - - storeClientCopy(asState->sc, e, remainingSpace, asHandleReply, asState); -} - -/** - * add a network (addr, mask) to the radix tree, with matching AS number - */ -static int -asnAddNet(const SBuf &addressAndMask, const int as_number) -{ - struct squid_radix_node *rn; - CbDataList **Tail = nullptr; - CbDataList *q = nullptr; - as_info *asinfo = nullptr; - - static const CharacterSet NonSlashSet = CharacterSet("slash", "/").complement("non-slash"); - Parser::Tokenizer tok(addressAndMask); - SBuf addressToken; - if (!(tok.prefix(addressToken, NonSlashSet) && tok.skip('/'))) { - debugs(53, 3, "asnAddNet: failed, invalid response from whois server."); - return 0; - } - const Ip::Address addr = addressToken.c_str(); - - // INET6 TODO : find a better way of identifying the base IPA family for mask than this. - const auto addrFamily = (addressToken.find('.') != SBuf::npos) ? AF_INET : AF_INET6; - - // generate Netbits Format Mask - Ip::Address mask; - mask.setNoAddr(); - int64_t bitl = 0; - if (tok.int64(bitl, 10, false)) - mask.applyMask(bitl, addrFamily); - - debugs(53, 3, "asnAddNet: called for " << addr << "/" << mask ); - - rtentry_t *e = (rtentry_t *)xcalloc(1, sizeof(rtentry_t)); - - e->e_addr.addr = addr; - - e->e_mask.addr = mask; - - rn = squid_rn_lookup(&e->e_addr, &e->e_mask, AS_tree_head); - - if (rn != nullptr) { - asinfo = ((rtentry_t *) rn)->e_info; - - if (asinfo->as_number->find(as_number)) { - debugs(53, 3, "asnAddNet: Ignoring repeated network '" << addr << "/" << bitl << "' for AS " << as_number); - } else { - debugs(53, 3, "asnAddNet: Warning: Found a network with multiple AS numbers!"); - - for (Tail = &asinfo->as_number; *Tail; Tail = &(*Tail)->next); - q = new CbDataList (as_number); - - *(Tail) = q; - - e->e_info = asinfo; - } - } else { - q = new CbDataList (as_number); - asinfo = (as_info *)xmalloc(sizeof(as_info)); - asinfo->as_number = q; - squid_rn_addroute(&e->e_addr, &e->e_mask, AS_tree_head, e->e_nodes); - rn = squid_rn_match(&e->e_addr, AS_tree_head); - assert(rn != nullptr); - e->e_info = asinfo; - } - - if (rn == nullptr) { /* assert might expand to nothing */ - xfree(asinfo); - delete q; - xfree(e); - debugs(53, 3, "asnAddNet: Could not add entry."); - return 0; - } - - e->e_info = asinfo; - return 1; -} - -static int -destroyRadixNode(struct squid_radix_node *rn, void *w) -{ - - struct squid_radix_node_head *rnh = (struct squid_radix_node_head *) w; - - if (rn && !(rn->rn_flags & RNF_ROOT)) { - rtentry_t *e = (rtentry_t *) rn; - rn = squid_rn_delete(rn->rn_key, rn->rn_mask, rnh); - - if (rn == nullptr) - debugs(53, 3, "destroyRadixNode: internal screwup"); - - destroyRadixNodeInfo(e->e_info); - - xfree(rn); - } - - return 1; -} - -static void -destroyRadixNodeInfo(as_info * e_info) -{ - CbDataList *prev = nullptr; - CbDataList *data = e_info->as_number; - - while (data) { - prev = data; - data = data->next; - delete prev; - } -} - -static int -printRadixNode(struct squid_radix_node *rn, void *_sentry) -{ - StoreEntry *sentry = (StoreEntry *)_sentry; - rtentry_t *e = (rtentry_t *) rn; - CbDataList *q; - as_info *asinfo; - char buf[MAX_IPSTRLEN]; - Ip::Address addr; - Ip::Address mask; - - assert(e); - assert(e->e_info); - addr = e->e_addr.addr; - mask = e->e_mask.addr; - storeAppendPrintf(sentry, "%s/%d\t", - addr.toStr(buf, MAX_IPSTRLEN), - mask.cidr() ); - asinfo = e->e_info; - assert(asinfo->as_number); - - for (q = asinfo->as_number; q; q = q->next) - storeAppendPrintf(sentry, " %d", q->element); - - storeAppendPrintf(sentry, "\n"); - - return 0; -} - -ACLASN::~ACLASN() -{ - if (data) - delete data; -} - -bool - -ACLASN::match(Ip::Address toMatch) -{ - return asnMatchIp(data, toMatch); -} - -SBufList -ACLASN::dump() const -{ - SBufList sl; - - CbDataList *ldata = data; - - while (ldata != nullptr) { - SBuf s; - s.Printf("%d", ldata->element); - sl.push_back(s); - ldata = ldata->next; - } - - return sl; -} - -bool -ACLASN::empty () const -{ - return data == nullptr; -} - -void -ACLASN::parse() -{ - CbDataList **curlist = &data; - CbDataList **Tail; - CbDataList *q = nullptr; - char *t = nullptr; - - for (Tail = curlist; *Tail; Tail = &((*Tail)->next)); - while ((t = ConfigParser::strtokFile())) { - q = new CbDataList (atoi(t)); - *(Tail) = q; - Tail = &q->next; - } -} - -int -Acl::SourceAsnCheck::match(ACLChecklist * const ch) -{ - const auto checklist = Filled(ch); - - return data->match(checklist->src_addr); -} - -int -Acl::DestinationAsnCheck::match(ACLChecklist * const ch) -{ - const auto checklist = Filled(ch); - - const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->url.host(), IP_LOOKUP_IF_MISS); - - if (ia) { - for (const auto &ip: ia->goodAndBad()) { - if (data->match(ip)) - return 1; - } - - return 0; - - } else if (!checklist->request->flags.destinationIpLookedUp) { - /* No entry in cache, lookup not attempted */ - debugs(28, 3, "can't yet compare '" << name << "' ACL for " << checklist->request->url.host()); - if (checklist->goAsync(ACLDestinationIP::StartLookup, *this)) - return -1; - // else fall through to noaddr match, hiding the lookup failure (XXX) - } - Ip::Address noaddr; - noaddr.setNoAddr(); - return data->match(noaddr); -} - diff --git a/src/acl/Asn.h b/src/acl/Asn.h deleted file mode 100644 index cf288432c4..0000000000 --- a/src/acl/Asn.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 1996-2025 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID_SRC_ACL_ASN_H -#define SQUID_SRC_ACL_ASN_H - -#include "acl/Data.h" -#include "base/CbDataList.h" -#include "ip/Address.h" - -int asnMatchIp(CbDataList *, Ip::Address &); - -/// \ingroup ACLAPI -void asnInit(void); - -/// \ingroup ACLAPI -void asnFreeMemory(void); - -/// \ingroup ACLAPI -class ACLASN : public ACLData -{ - MEMPROXY_CLASS(ACLASN); - -public: - ACLASN() : data(nullptr) {} - ~ACLASN() override; - - bool match(Ip::Address) override; - SBufList dump() const override; - void parse() override; - bool empty() const override; - void prepareForUse() override; - -private: - CbDataList *data; -}; - -#endif /* SQUID_SRC_ACL_ASN_H */ - diff --git a/src/acl/DestinationAsn.h b/src/acl/DestinationAsn.h deleted file mode 100644 index 4054e34d20..0000000000 --- a/src/acl/DestinationAsn.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 1996-2025 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID_SRC_ACL_DESTINATIONASN_H -#define SQUID_SRC_ACL_DESTINATIONASN_H - -#include "acl/Data.h" -#include "acl/ParameterizedNode.h" -#include "ip/forward.h" - -namespace Acl -{ - -/// a "dst_as" ACL -class DestinationAsnCheck: public ParameterizedNode< ACLData > -{ -public: - /* Acl::Node API */ - int match(ACLChecklist *) override; - bool requiresRequest() const override {return true;} -}; - -} // namespace Acl - -#endif /* SQUID_SRC_ACL_DESTINATIONASN_H */ - diff --git a/src/acl/Makefile.am b/src/acl/Makefile.am index e4957bb538..cb27b85086 100644 --- a/src/acl/Makefile.am +++ b/src/acl/Makefile.am @@ -56,8 +56,6 @@ libacls_la_SOURCES = \ AnnotationData.h \ AnyOf.cc \ AnyOf.h \ - Asn.cc \ - Asn.h \ AtStep.cc \ AtStep.h \ AtStepData.cc \ @@ -66,7 +64,6 @@ libacls_la_SOURCES = \ ConnMark.h \ ConnectionsEncrypted.cc \ ConnectionsEncrypted.h \ - DestinationAsn.h \ DestinationDomain.cc \ DestinationDomain.h \ DestinationIp.cc \ @@ -127,7 +124,6 @@ libacls_la_SOURCES = \ ReplyMimeType.h \ RequestHeaderStrategy.h \ RequestMimeType.h \ - SourceAsn.h \ SourceDomain.cc \ SourceDomain.h \ SourceIp.cc \ diff --git a/src/acl/SourceAsn.h b/src/acl/SourceAsn.h deleted file mode 100644 index f5c88336d0..0000000000 --- a/src/acl/SourceAsn.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 1996-2025 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID_SRC_ACL_SOURCEASN_H -#define SQUID_SRC_ACL_SOURCEASN_H - -#include "acl/Data.h" -#include "acl/ParameterizedNode.h" -#include "ip/forward.h" - -namespace Acl -{ - -/// a "src_as" ACL -class SourceAsnCheck: public ParameterizedNode< ACLData > -{ -public: - /* Acl::Node API */ - int match(ACLChecklist *) override; -}; - -} // namespace Acl - -#endif /* SQUID_SRC_ACL_SOURCEASN_H */ - diff --git a/src/cf.data.pre b/src/cf.data.pre index d90e674996..3fca75897c 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1225,17 +1225,6 @@ ENDIF # based URL is used and no match is found. The name "none" is used # if the reverse lookup fails. - acl aclname src_as number ... - acl aclname dst_as number ... - # [fast] - # Except for access control, AS numbers can be used for - # routing of requests to specific caches. Here's an - # example for routing all requests for AS#1241 and only - # those to mycache.mydomain.net: - # acl asexample dst_as 1241 - # cache_peer_access mycache.mydomain.net allow asexample - # cache_peer_access mycache_mydomain.net deny all - acl aclname peername myPeer ... acl aclname peername_regex [-i] regex-pattern ... # [fast] @@ -1511,7 +1500,6 @@ ENDIF # htcp: matches HTCP requests from peers # icp: matches ICP requests to peers # icmp: matches ICMP RTT database (NetDB) requests to peers - # asn: matches asns db requests # internal: matches any of the above # client: matches transactions containing an HTTP or FTP # client request received at a Squid *_port @@ -1698,7 +1686,6 @@ ENDIF Examples: acl macaddress arp 09:00:2b:23:45:67 - acl myexample dst_as 1241 acl password proxy_auth REQUIRED acl fileupload req_mime_type -i ^multipart/form-data$ acl javascript rep_mime_type -i ^application/x-javascript$ @@ -10345,7 +10332,6 @@ DOC_START Some valid actions are (see cache manager menu for a full list): 5min 60min - asndb authenticator cbdata client_list diff --git a/src/main.cc b/src/main.cc index 9b4a46f816..3e676752ae 100644 --- a/src/main.cc +++ b/src/main.cc @@ -11,7 +11,6 @@ #include "squid.h" #include "AccessLogEntry.h" //#include "acl/Acl.h" -#include "acl/Asn.h" #include "acl/forward.h" #include "anyp/UriScheme.h" #include "auth/Config.h" @@ -790,7 +789,6 @@ serverConnectionsOpen(void) icmpEngine.Open(); netdbInit(); - asnInit(); Acl::Node::Initialize(); peerSelectInit(); } @@ -812,8 +810,6 @@ serverConnectionsClose(void) #if SQUID_SNMP snmpClosePorts(); #endif - - asnFreeMemory(); } }