DomainData.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 28 Access Control */
10 
11 #include "squid.h"
12 #include "acl/Checklist.h"
13 #include "acl/DomainData.h"
14 #include "acl/SplayInserter.h"
15 #include "anyp/Uri.h"
16 #include "cache_cf.h"
17 #include "ConfigParser.h"
18 #include "debug/Stream.h"
19 #include "util.h"
20 
21 template<class T>
22 inline void
23 xRefFree(T &thing)
24 {
25  xfree (thing);
26 }
27 
29 {
31 }
32 
33 template<class T>
34 inline int
35 splaystrcasecmp (T&l, T&r)
36 {
37  return strcasecmp ((char *)l,(char *)r);
38 }
39 
40 template<class T>
41 inline int
42 splaystrcmp (T&l, T&r)
43 {
44  return strcmp ((char *)l,(char *)r);
45 }
46 
47 /* general compare functions, these are used for tree search algorithms
48  * so they return <0, 0 or >0 */
49 
50 /* compare a host and a domain */
51 
52 static int
53 aclHostDomainCompare( char *const &a, char * const &b)
54 {
55  const char *h = static_cast<const char *>(a);
56  const char *d = static_cast<const char *>(b);
57  return matchDomainName(h, d);
58 }
59 
60 bool
61 ACLDomainData::match(char const *host)
62 {
63  if (!host)
64  return false;
65 
66  debugs(28, 3, "aclMatchDomainList: checking '" << host << "'");
67 
68  char *h = const_cast<char *>(host);
69  const auto result = domains.find(h, aclHostDomainCompare);
70 
71  debugs(28, 3, "aclMatchDomainList: '" << host << "' " << (result ? "found" : "NOT found"));
72 
73  return (result != nullptr);
74 }
75 
78  void operator() (char * const & node_data) {
79  contents.push_back(SBuf(node_data));
80  }
81 };
82 
85 {
87  domains.visit(visitor);
88  return visitor.contents;
89 }
90 
91 template <>
92 int
94 {
95  // If X represents a set of matching domain names (e.g., .example.com), then
96  // matchDomainName(X, Y) uses a single domain name from X by removing the
97  // leading dot (e.g., example.com). We call that name "the root of X". If X
98  // is a single domain name, then its root is X itself. Since domain sets
99  // cannot have _partial_ overlaps (unlike IP or integer ranges), testing
100  // roots is enough to detect duplicates and establish correct set order.
101 
102  if (matchDomainName(b, a)) {
103  // Set A does not contain B's root. If set B contains A's root, then the
104  // call below will return 0, signaling duplicates. Otherwise, A and B
105  // have no common values, and the call below will correctly order the
106  // two sets, mimicking the order used by the Splay comparison function
107  // in match().
108  return matchDomainName(a, b);
109  } else {
110  // Signal duplicates because set A contains B's root (at least).
111  return 0;
112  }
113 }
114 
115 template <>
116 bool
118 {
119  // A value that starts with a dot matches a set of the corresponding domain
120  // names. Other values are individual domain names that match themselves.
121  // \sa matchDomainName()
122 
123  if (*a == '.' && *b == '.') {
124  // A and B are overlapping sets. More characters imply a smaller set.
125  return strlen(a) >= strlen(b);
126  }
127 
128  if (*a != '.' && *b != '.') {
129  // A and B are identical individual domain names
130  return true;
131  }
132 
133  // Either A or B is a set. The other one is a domain name inside that set.
134  // That domain name may use fewer or more characters (e.g., both example.com
135  // and x.example.com domains belong to the same .example.com set), so we
136  // cannot use a strlen()-based test here.
137  return *b == '.';
138 }
139 
140 template <>
143 {
144  Assure(!"domain name sets cannot partially overlap");
145  return nullptr; // unreachable code
146 }
147 
148 template <>
149 void
151 {
152  xfree(v);
153 }
154 
155 void
157 {
158  while (char *t = ConfigParser::strtokFile()) {
159  Tolower(t);
161  }
162 }
163 
164 bool
166 {
167  return domains.empty();
168 }
169 
void operator()(char *const &node_data)
Definition: DomainData.cc:78
static int Compare(const Value &a, const Value &b)
const Value * find(FindValue const &, int(*compare)(FindValue const &a, Value const &b)) const
Definition: splay.h:305
void visit(ValueVisitor &) const
left-to-right visit of all stored Values
void xRefFree(T &thing)
Definition: DomainData.cc:23
SBufList dump() const override
Definition: DomainData.cc:84
int splaystrcmp(T &l, T &r)
Definition: DomainData.cc:42
static char * strtokFile()
Definition: ConfigParser.cc:65
bool empty() const
Definition: splay.h:78
static int aclHostDomainCompare(char *const &a, char *const &b)
Definition: DomainData.cc:53
Splay< char * > domains
Definition: DomainData.h:28
void parse() override
Definition: DomainData.cc:156
std::list< SBuf > SBufList
Definition: forward.h:22
Definition: SBuf.h:93
#define xstrdup
int matchDomainName(const char *h, const char *d, MatchDomainNameFlags flags)
Definition: Uri.cc:903
bool match(char const *) override
Definition: DomainData.cc:61
static Value MakeCombinedValue(const Value &a, const Value &b)
static void Merge(Splay< Value > &, Value &&)
Definition: SplayInserter.h:68
void Tolower(char *)
Definition: util.cc:28
bool empty() const override
Definition: DomainData.cc:165
#define Assure(condition)
Definition: Assure.h:35
#define xfree
void destroy(SPLAYFREE *=DefaultFree)
Definition: splay.h:369
int splaystrcasecmp(T &l, T &r)
Definition: DomainData.cc:35
~ACLDomainData() override
Definition: DomainData.cc:28
static void DestroyValue(Value v)
A Splay::SPLAYFREE-like function that destroys parsed ACL parameter values.
Definition: SplayInserter.h:61
static bool IsSubset(const Value &a, const Value &b)
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192

 

Introduction

Documentation

Support

Miscellaneous