Ip.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/Ip.h"
14 #include "acl/SplayInserter.h"
15 #include "cache_cf.h"
16 #include "ConfigParser.h"
17 #include "debug/Stream.h"
18 #include "ip/tools.h"
19 #include "MemBuf.h"
20 #include "wordlist.h"
21 
22 #include <algorithm>
23 
24 void *
25 ACLIP::operator new (size_t)
26 {
27  fatal ("ACLIP::operator new: unused");
28  return (void *)1;
29 }
30 
31 void
32 ACLIP::operator delete (void *)
33 {
34  fatal ("ACLIP::operator delete: unused");
35 }
36 
43 void
44 acl_ip_data::toStr(char *buf, int len) const
45 {
46  char *b1 = buf;
47  char *b2 = nullptr;
48  char *b3 = nullptr;
49  int rlen = 0;
50 
51  addr1.toStr(b1, len - rlen );
52  rlen = strlen(buf);
53  b2 = buf + rlen;
54 
55  if (!addr2.isAnyAddr()) {
56  b2[0] = '-';
57  ++rlen;
58  addr2.toStr(&(b2[1]), len - rlen );
59  rlen = strlen(buf);
60  } else
61  b2[0] = '\0';
62 
63  b3 = buf + rlen;
64 
65  if (!mask.isNoAddr()) {
66  b3[0] = '/';
67  ++rlen;
68  int cidr = mask.cidr() - (addr1.isIPv4()?96:0);
69  snprintf(&(b3[1]), (len-rlen), "%u", (unsigned int)(cidr<0?0:cidr) );
70  } else
71  b3[0] = '\0';
72 }
73 
74 SBuf
76 {
77  const int bufsz = MAX_IPSTRLEN*2+6;
78  static char tmpbuf[ bufsz ];
79  toStr(tmpbuf,bufsz);
80  return SBuf(tmpbuf);
81 }
82 
85 {
86  auto ip = addr1;
87  if (!mask.isNoAddr())
88  ip.applyMask(mask);
89  return ip;
90 }
91 
94 {
95  auto ip = addr2.isAnyAddr() ? addr1 : addr2;
96  if (!mask.isNoAddr())
98  return ip;
99 }
100 
101 template <>
102 int
104 {
105  if (a->lastAddress() < b->firstAddress())
106  return -1; // the entire range a is to the left of range b
107 
108  if (a->firstAddress() > b->lastAddress())
109  return +1; // the entire range a is to the right of range b
110 
111  return 0; // equal or partially overlapping ranges
112 }
113 
114 template <>
115 bool
117 {
118  return b->firstAddress() <= a->firstAddress() && a->lastAddress() <= b->lastAddress();
119 }
120 
121 template <>
124 {
125  const auto minLeft = std::min(a->firstAddress(), b->firstAddress());
126  const auto maxRight = std::max(a->lastAddress(), b->lastAddress());
127  return new acl_ip_data(minLeft, maxRight, Ip::Address::NoAddr(), nullptr);
128 }
129 
131 static std::ostream &
132 operator <<(std::ostream &os, acl_ip_data *value)
133 {
134  if (value)
135  os << value->toSBuf();
136  return os;
137 }
138 
139 /*
140  * aclIpAddrNetworkCompare - The guts of the comparison for IP ACLs
141  * matching checks. The first argument (p) is a "host" address,
142  * i.e. the IP address of a cache client. The second argument (q)
143  * is an entry in some address-based access control element. This
144  * function is called via ACLIP::match() and the splay library.
145  */
146 static int
148 {
149  Ip::Address A = p->addr1;
150 
151  /* apply netmask */
152  A.applyMask(q->mask);
153 
154  debugs(28,9, "aclIpAddrNetworkCompare: compare: " << p->addr1 << "/" << q->mask << " (" << A << ") vs " <<
155  q->addr1 << "-" << q->addr2 << "/" << q->mask);
156 
157  if (q->addr2.isAnyAddr()) { /* single address check */
158 
159  return A.matchIPAddr( q->addr1 );
160 
161  } else { /* range address check */
162 
163  if ( (A >= q->addr1) && (A <= q->addr2) )
164  return 0; /* valid. inside range. */
165  else
166  return A.matchIPAddr( q->addr1 ); /* outside of range, 'less than' */
167  }
168 }
169 
175 bool
176 acl_ip_data::DecodeMask(const char *asc, Ip::Address &mask, int ctype)
177 {
178  char junk;
179  int a1 = 0;
180 
181  /* default is a mask that doesn't change any IP */
182  mask.setNoAddr();
183 
184  if (!asc || !*asc) {
185  return true;
186  }
187 
188  /* An int mask 128, 32 */
189  if ((sscanf(asc, "%d%c", &a1, &junk)==1) &&
190  (a1 <= 128) && (a1 >= 0)
191  ) {
192  return mask.applyMask(a1, ctype);
193  }
194 
195  /* dotted notation */
196  /* assignment returns true if asc contained an IP address as text */
197  if ((mask = asc)) {
198  /* HACK: IPv4 netmasks don't cleanly map to IPv6 masks. */
199  debugs(28, DBG_CRITICAL, "WARNING: Netmasks are deprecated. Please use CIDR masks instead.");
200  if (mask.isIPv4()) {
201  /* locate what CIDR mask was _probably_ meant to be in its native protocol format. */
202  /* this will completely crap out with a security fail-open if the admin is playing mask tricks */
203  /* however, that's their fault, and we do warn. see bug 2601 for the effects if we don't do this. */
204  unsigned int m = mask.cidr();
205  debugs(28, DBG_CRITICAL, "WARNING: IPv4 netmasks are particularly nasty when used to compare IPv6 to IPv4 ranges.");
206  debugs(28, DBG_CRITICAL, "WARNING: For now we will assume you meant to write /" << m);
207  /* reset the mask completely, and crop to the CIDR boundary back properly. */
208  mask.setNoAddr();
209  return mask.applyMask(m,AF_INET);
210  }
211  return true;
212  }
213 
214  return false;
215 }
216 
218 bool
220 {
221  // XXX: FactoryParse() adds an item and only then checks its validity. This
222  // loop excludes the last (i.e. being vetted) item. TODO: Refactor parsing
223  // to use a temporary container of vetted items instead of the current
224  // acl_ip_data::next hack.
225  for (const auto *i = this; i && i->next; i = i->next) {
226  if (i->addr1 == needle)
227  return true;
228  }
229  return false;
230 }
231 
232 /* Handle either type of address, IPv6 will be discarded with a warning if disabled */
233 #define SCAN_ACL1_6 "%[0123456789ABCDEFabcdef:]-%[0123456789ABCDEFabcdef:]/%[0123456789]"
234 #define SCAN_ACL2_6 "%[0123456789ABCDEFabcdef:]-%[0123456789ABCDEFabcdef:]%c"
235 #define SCAN_ACL3_6 "%[0123456789ABCDEFabcdef:]/%[0123456789]"
236 #define SCAN_ACL4_6 "%[0123456789ABCDEFabcdef:]/%c"
237 /* We DO need to know which is which though, for proper CIDR masking. */
238 #define SCAN_ACL1_4 "%[0123456789.]-%[0123456789.]/%[0123456789.]"
239 #define SCAN_ACL2_4 "%[0123456789.]-%[0123456789.]%c"
240 #define SCAN_ACL3_4 "%[0123456789.]/%[0123456789.]"
241 #define SCAN_ACL4_4 "%[0123456789.]/%c"
242 
243 acl_ip_data *
245 {
246  LOCAL_ARRAY(char, addr1, 256);
247  LOCAL_ARRAY(char, addr2, 256);
248  LOCAL_ARRAY(char, mask, 256);
249  acl_ip_data *r = nullptr;
250  acl_ip_data **Q = nullptr;
251  Ip::Address temp;
252  char c;
253  unsigned int changed;
254  acl_ip_data *q = new acl_ip_data;
255  int iptype = AF_UNSPEC;
256 
257  debugs(28, 5, "aclIpParseIpData: " << t);
258 
259 // IPv4
260  if (sscanf(t, SCAN_ACL1_4, addr1, addr2, mask) == 3) {
261  debugs(28, 9, "aclIpParseIpData: '" << t << "' matched: SCAN1-v4: " << SCAN_ACL1_4);
262  iptype=AF_INET;
263  } else if (sscanf(t, SCAN_ACL2_4, addr1, addr2, &c) >= 2) {
264  debugs(28, 9, "aclIpParseIpData: '" << t << "' matched: SCAN2-v4: " << SCAN_ACL2_4);
265  mask[0] = '\0';
266  iptype=AF_INET;
267  } else if (sscanf(t, SCAN_ACL3_4, addr1, mask) == 2) {
268  debugs(28, 9, "aclIpParseIpData: '" << t << "' matched: SCAN3-v4: " << SCAN_ACL3_4);
269  addr2[0] = '\0';
270  iptype=AF_INET;
271  } else if (sscanf(t, SCAN_ACL4_4, addr1,&c) == 2) {
272  debugs(28, 9, "aclIpParseIpData: '" << t << "' matched: SCAN4-v4: " << SCAN_ACL4_4);
273  addr2[0] = '\0';
274  mask[0] = '\0';
275  iptype=AF_INET;
276 
277 // IPv6
278  } else if (sscanf(t, SCAN_ACL1_6, addr1, addr2, mask) == 3) {
279  debugs(28, 9, "aclIpParseIpData: '" << t << "' matched: SCAN1-v6: " << SCAN_ACL1_6);
280  iptype=AF_INET6;
281  } else if (sscanf(t, SCAN_ACL2_6, addr1, addr2, &c) >= 2) {
282  debugs(28, 9, "aclIpParseIpData: '" << t << "' matched: SCAN2-v6: " << SCAN_ACL2_6);
283  mask[0] = '\0';
284  iptype=AF_INET6;
285  } else if (sscanf(t, SCAN_ACL3_6, addr1, mask) == 2) {
286  debugs(28, 9, "aclIpParseIpData: '" << t << "' matched: SCAN3-v6: " << SCAN_ACL3_6);
287  addr2[0] = '\0';
288  iptype=AF_INET6;
289  } else if (sscanf(t, SCAN_ACL4_6, addr1, mask) == 2) {
290  debugs(28, 9, "aclIpParseIpData: '" << t << "' matched: SCAN4-v6: " << SCAN_ACL4_6);
291  addr2[0] = '\0';
292  iptype=AF_INET6;
293 
294 // Neither
295  } else if (sscanf(t, "%[^/]/%s", addr1, mask) == 2) {
296  debugs(28, 9, "aclIpParseIpData: '" << t << "' matched: non-IP pattern: %[^/]/%s");
297  addr2[0] = '\0';
298  } else if (sscanf(t, "%s", addr1) == 1) {
299  /*
300  * Note, must use plain getaddrinfo() here because at startup
301  * ipcache hasn't been initialized
302  * TODO: offload this to one of the Ip::Address lookups.
303  */
304 
305  debugs(28, 5, "aclIpParseIpData: Lookup Host/IP " << addr1);
306  struct addrinfo *hp = nullptr, *x = nullptr;
307  struct addrinfo hints;
308 
309  memset(&hints, 0, sizeof(struct addrinfo));
310 
311  int errcode = getaddrinfo(addr1,nullptr,&hints,&hp);
312  if (hp == nullptr) {
313  delete q;
314  if (strcmp(addr1, "::1") == 0) {
315  debugs(28, DBG_IMPORTANT, "aclIpParseIpData: IPv6 has not been enabled in host DNS resolver.");
316  } else {
317  debugs(28, DBG_CRITICAL, "ERROR: aclIpParseIpData: Bad host/IP: '" << addr1 <<
318  "' in '" << t << "', flags=" << hints.ai_flags <<
319  " : (" << errcode << ") " << gai_strerror(errcode) );
320  self_destruct();
321  }
322  return nullptr;
323  }
324 
325  Q = &q;
326 
327  for (x = hp; x != nullptr;) {
328  if ((r = *Q) == nullptr)
329  r = *Q = new acl_ip_data;
330 
331  r->addr1 = *x;
332  x = x->ai_next;
333  if (q->containsVetted(r->addr1)) {
334  // getaddrinfo() returned duplicate ai_addr values; we have already added one of them
335  debugs(28, 3, "aclIpParseIpData: Duplicate host/IP: '" << r->addr1 << "' dropped.");
336  delete r;
337  *Q = nullptr;
338  continue;
339  }
340 
341  debugs(28, 3, "aclIpParseIpData: Located host/IP: '" << r->addr1 << "'");
342 
343  r->addr2.setAnyAddr();
344  r->mask.setNoAddr();
345 
346  Q = &r->next;
347 
348  debugs(28, 3, "" << addr1 << " --> " << r->addr1 );
349  }
350 
351  freeaddrinfo(hp);
352 
353  if (*Q != nullptr) {
354  debugs(28, DBG_CRITICAL, "ERROR: aclIpParseIpData: Bad host/IP: '" << t << "'");
355  self_destruct();
356  return nullptr;
357  }
358 
359  return q;
360  }
361 
362  /* ignore IPv6 addresses when built with IPv4-only */
363  if ( iptype == AF_INET6 && !Ip::EnableIpv6) {
364  debugs(28, DBG_IMPORTANT, "aclIpParseIpData: IPv6 has not been enabled.");
365  delete q;
366  return nullptr;
367  }
368 
369  /* Decode addr1 */
370  if (!*addr1 || !(q->addr1 = addr1)) {
371  debugs(28, DBG_CRITICAL, "ERROR: aclIpParseIpData: unknown first address in '" << t << "'");
372  delete q;
373  self_destruct();
374  return nullptr;
375  }
376 
377  /* Decode addr2 */
378  if (!*addr2)
379  q->addr2.setAnyAddr();
380  else if (!(q->addr2=addr2) ) {
381  debugs(28, DBG_CRITICAL, "ERROR: aclIpParseIpData: unknown second address in '" << t << "'");
382  delete q;
383  self_destruct();
384  return nullptr;
385  }
386 
387  /* Decode mask (NULL or empty means a exact host mask) */
388  if (!DecodeMask(mask, q->mask, iptype)) {
389  debugs(28, DBG_CRITICAL, "ERROR: aclParseIpData: unknown netmask '" << mask << "' in '" << t << "'");
390  delete q;
391  self_destruct();
392  return nullptr;
393  }
394 
395  changed = 0;
396  changed += q->addr1.applyMask(q->mask);
397  changed += q->addr2.applyMask(q->mask);
398 
399  if (changed)
400  debugs(28, DBG_CRITICAL, "WARNING: aclIpParseIpData: Netmask masks away part of the specified IP in '" << t << "'");
401 
402  // TODO: Either switch match() to Acl::SplayInserter<acl_ip_data*>::Compare()
403  // range logic (that does not have these problems) OR warn that some (or
404  // even all) addresses will never match this configured ACL value when
405  // `q->addr1.applyMask()` above is positive:
406  //
407  // * A single configured IP value will never match:
408  // A.matchIPAddr(q->addr1) in aclIpAddrNetworkCompare() will not return 0.
409  // For example, `acl x src 127.0.0.1/24` does not match any address.
410  //
411  // * A configured IP range will not match any q->addr1/mask IPs:
412  // (A >= q->addr1) in aclIpAddrNetworkCompare() is false and
413  // A.matchIPAddr(q->addr1) will not return 0.
414  // For example, `acl y src 10.0.0.1-10.0.0.255/24` does not match 10.0.0.1.
415 
416  debugs(28,9, "Parsed: " << q->addr1 << "-" << q->addr2 << "/" << q->mask << "(/" << q->mask.cidr() <<")");
417 
418  /* 1.2.3.4/255.255.255.0 --> 1.2.3.0 */
419  /* Same as IPv6 (not so trivial to depict) */
420  return q;
421 }
422 
425 bool
426 ACLIP::parseGlobal(const char * const token)
427 {
428  // "all" matches entire Internet
429  if (strcmp(token, "all") == 0) {
430  debugs(28, 8, "found " << token);
431  matchAnyIpv4 = true;
432  matchAnyIpv6 = true;
433  // TODO: Ignore all other ACL data parameters, with a once/ACL warning.
434  return true;
435  }
436 
437  // "ipv4" matches IPv4 Internet
438  if (strcmp(token, "ipv4") == 0) {
439  debugs(28, 8, "found " << token);
440  matchAnyIpv4 = true;
441  // TODO: Ignore all IPv4 data parameters, with a once/ACL warning.
442  return true;
443  }
444 
445  // "ipv4" matches IPv6 Internet
446  if (strcmp(token, "ipv6") == 0) {
447  debugs(28, 8, "found " << token);
448  matchAnyIpv6 = true;
449  // TODO: Ignore all IPv6 data parameters, with a once/ACL warning.
450  return true;
451  }
452 
453  /* Detect some old broken strings equivalent to 'all'.
454  * treat them nicely. But be loud until its fixed. */
455  if (strcmp(token, "0/0") == 0 ||
456  strcmp(token, "0.0.0.0/0") == 0 ||
457  strcmp(token, "0.0.0.0/0.0.0.0") == 0 ||
458  strcmp(token, "0.0.0.0-255.255.255.255") == 0 ||
459  strcmp(token, "0.0.0.0-0.0.0.0/0") == 0) {
460 
461  debugs(28,DBG_CRITICAL, "ERROR: '" << token << "' needs to be replaced by the term 'all'.");
462  debugs(28,DBG_CRITICAL, "SECURITY NOTICE: Overriding config setting. Using 'all' instead.");
463  matchAnyIpv4 = true;
464  matchAnyIpv6 = true;
465  return true;
466  }
467 
468  return false;
469 }
470 
471 void
473 {
474  if (data == nullptr)
475  data = new IPSplay();
476 
477  while (char *t = ConfigParser::strtokFile()) {
478  if (parseGlobal(t))
479  continue;
480 
482 
483  while (q != nullptr) {
484  /* pop each result off the list and add it to the data tree individually */
485  acl_ip_data *next_node = q->next;
486  q->next = nullptr;
488  q = next_node;
489  }
490  }
491 }
492 
494 {
495  if (data) {
496  data->destroy();
497  delete data;
498  }
499 }
500 
503  void operator() (acl_ip_data * const & ip) {
504  contents.push_back(ip->toSBuf());
505  }
506 };
507 
508 SBufList
509 ACLIP::dump() const
510 {
511  IpAclDumpVisitor visitor;
512 
513  if (matchAnyIpv4 && matchAnyIpv6)
514  visitor.contents.push_back(SBuf("all"));
515  else if (matchAnyIpv4)
516  visitor.contents.push_back(SBuf("ipv4"));
517  else if (matchAnyIpv6)
518  visitor.contents.push_back(SBuf("ipv6"));
519 
520  data->visit(visitor);
521  return visitor.contents;
522 }
523 
524 bool
526 {
527  return data->empty() && !matchAnyIpv4 && !matchAnyIpv6;
528 }
529 
530 int
531 ACLIP::match(const Ip::Address &clientip)
532 {
533  if (matchAnyIpv4) {
534  if (matchAnyIpv6) {
535  debugs(28, 3, clientip << " found, matched 'all'");
536  return true;
537  }
538  if (clientip.isIPv4()) {
539  debugs(28, 3, clientip << " found, matched 'ipv4'");
540  return true;
541  }
542  // fall through to look for an IPv6 match among IP parameters
543  } else if (matchAnyIpv6) {
544  if (clientip.isIPv6()) {
545  debugs(28, 3, clientip << " found, matched 'ipv6'");
546  return true;
547  }
548  // fall through to look for an IPv4 match among IP parameters
549  }
550 
551  static acl_ip_data ClientAddress;
552  /*
553  * aclIpAddrNetworkCompare() takes two acl_ip_data pointers as
554  * arguments, so we must create a fake one for the client's IP
555  * address. Since we are scanning for a single IP mask and addr2
556  * MUST be set to empty.
557  */
558  ClientAddress.addr1 = clientip;
559  ClientAddress.addr2.setEmpty();
560  ClientAddress.mask.setEmpty();
561 
562  const acl_ip_data * const * result = data->find(&ClientAddress, aclIpAddrNetworkCompare);
563  debugs(28, 3, "aclIpMatchIp: '" << clientip << "' " << (result ? "found" : "NOT found"));
564  return (result != nullptr);
565 }
566 
567 acl_ip_data::acl_ip_data() :addr1(), addr2(), mask(), next (nullptr) {}
568 
569 acl_ip_data::acl_ip_data(Ip::Address const &anAddress1, Ip::Address const &anAddress2, Ip::Address const &aMask, acl_ip_data *aNext) : addr1(anAddress1), addr2(anAddress2), mask(aMask), next(aNext) {}
570 
IPSplay * data
Definition: Ip.h:72
void fatal(const char *message)
Definition: fatal.cc:28
static int aclIpAddrNetworkCompare(acl_ip_data *const &p, acl_ip_data *const &q)
Definition: Ip.cc:147
SBuf toSBuf() const
Definition: Ip.cc:75
void turnMaskedBitsOn(const Address &mask)
Definition: Address.cc:115
static int Compare(const Value &a, const Value &b)
bool empty() const override
Definition: Ip.cc:525
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
#define DBG_CRITICAL
Definition: Stream.h:37
#define SCAN_ACL3_4
Definition: Ip.cc:240
static char * strtokFile()
Definition: ConfigParser.cc:65
#define LOCAL_ARRAY(type, name, size)
Definition: squid.h:62
bool empty() const
Definition: splay.h:78
bool parseGlobal(const char *)
Definition: Ip.cc:426
static std::ostream & operator<<(std::ostream &os, acl_ip_data *value)
reports acl_ip_data using squid.conf ACL value format
Definition: Ip.cc:132
bool isAnyAddr() const
Definition: Address.cc:190
std::list< SBuf > SBufList
Definition: forward.h:22
SBufList contents
Definition: Ip.cc:502
Definition: SBuf.h:93
Ip::Address mask
Definition: Ip.h:40
void operator()(acl_ip_data *const &ip)
Definition: Ip.cc:503
const A & max(A const &lhs, A const &rhs)
Ip::Address addr2
Definition: Ip.h:38
bool isIPv4() const
Definition: Address.cc:178
#define SCAN_ACL4_4
Definition: Ip.cc:241
static Value MakeCombinedValue(const Value &a, const Value &b)
static void Merge(Splay< Value > &, Value &&)
Definition: SplayInserter.h:68
int const char size_t
Definition: stub_liblog.cc:83
void self_destruct(void)
Definition: cache_cf.cc:276
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
Definition: Address.cc:812
#define MAX_IPSTRLEN
Length of buffer that needs to be allocated to old a null-terminated IP-string.
Definition: forward.h:25
#define SCAN_ACL3_6
Definition: Ip.cc:235
void toStr(char *buf, int len) const
Definition: Ip.cc:44
void setNoAddr()
Definition: Address.cc:312
static uint32 A
Definition: md4.c:43
bool isIPv6() const
Definition: Address.cc:184
Ip::Address lastAddress() const
maximum (masked) address that matches this configured ACL value
Definition: Ip.cc:93
static const Address & NoAddr()
Definition: Address.h:321
bool matchAnyIpv6
whether match() should return 1 for any IPv6 parameter
Definition: Ip.h:81
Ip::Address addr1
Definition: Ip.h:36
bool containsVetted(const Ip::Address &needle) const
whether we have parsed and vetted an item with an addr1 field that matches the needle
Definition: Ip.cc:219
int cidr() const
Definition: Address.cc:54
Splay< acl_ip_data * > IPSplay
Definition: Ip.h:60
void setEmpty()
Fast reset of the stored content to what would be after default constructor.
Definition: Address.cc:204
bool isNoAddr() const
Definition: Address.cc:304
void destroy(SPLAYFREE *=DefaultFree)
Definition: splay.h:369
#define SCAN_ACL2_6
Definition: Ip.cc:234
SBufList dump() const override
Definition: Ip.cc:509
#define SCAN_ACL1_4
Definition: Ip.cc:238
int applyMask(const Address &mask)
Definition: Address.cc:97
int match(ACLChecklist *checklist) override=0
Matches the actual data in checklist against this Acl::Node.
static bool DecodeMask(const char *asc, Ip::Address &mask, int string_format_type)
Definition: Ip.cc:176
#define SCAN_ACL4_6
Definition: Ip.cc:236
~ACLIP() override
Definition: Ip.cc:493
Definition: Ip.h:17
Ip::Address firstAddress() const
minimum (masked) address that matches this configured ACL value
Definition: Ip.cc:84
void setAnyAddr()
NOTE: Does NOT clear the Port stored. Only the Address and Type.
Definition: Address.cc:197
#define DBG_IMPORTANT
Definition: Stream.h:38
#define SCAN_ACL1_6
Definition: Ip.cc:233
bool matchAnyIpv4
whether match() should return 1 for any IPv4 parameter
Definition: Ip.h:78
acl_ip_data()
Definition: Ip.cc:567
#define SCAN_ACL2_4
Definition: Ip.cc:239
int EnableIpv6
Whether IPv6 is supported and type of support.
Definition: tools.h:25
static bool IsSubset(const Value &a, const Value &b)
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
const A & min(A const &lhs, A const &rhs)
acl_ip_data * next
Definition: Ip.h:42
static acl_ip_data * FactoryParse(char const *)
Definition: Ip.cc:244
void parse() override
parses node representation in squid.conf; dies on failures
Definition: Ip.cc:472

 

Introduction

Documentation

Support

Miscellaneous