]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/DestinationDomain.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / acl / DestinationDomain.cc
1 /*
2 * Copyright (C) 1996-2014 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/DestinationDomain.h"
14 #include "acl/DomainData.h"
15 #include "acl/RegexData.h"
16 #include "fqdncache.h"
17 #include "HttpRequest.h"
18 #include "ipcache.h"
19
20 DestinationDomainLookup DestinationDomainLookup::instance_;
21
22 DestinationDomainLookup *
23 DestinationDomainLookup::Instance()
24 {
25 return &instance_;
26 }
27
28 void
29 DestinationDomainLookup::checkForAsync(ACLChecklist *cl) const
30 {
31 ACLFilledChecklist *checklist = Filled(cl);
32 fqdncache_nbgethostbyaddr(checklist->dst_addr, LookupDone, checklist);
33 }
34
35 void
36 DestinationDomainLookup::LookupDone(const char *fqdn, const DnsLookupDetails &details, void *data)
37 {
38 ACLFilledChecklist *checklist = Filled((ACLChecklist*)data);
39 checklist->markDestinationDomainChecked();
40 checklist->request->recordLookup(details);
41 checklist->resumeNonBlockingCheck(DestinationDomainLookup::Instance());
42 }
43
44 int
45 ACLDestinationDomainStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &flags)
46 {
47 assert(checklist != NULL && checklist->request != NULL);
48
49 if (data->match(checklist->request->GetHost())) {
50 return 1;
51 }
52
53 if (flags.isSet(ACL_F_NO_LOOKUP)) {
54 debugs(28, 3, "aclMatchAcl: No-lookup DNS ACL '" << AclMatchedName << "' for '" << checklist->request->GetHost() << "'");
55 return 0;
56 }
57
58 /* numeric IPA? no, trust the above result. */
59 if (checklist->request->GetHostIsNumeric() == 0) {
60 return 0;
61 }
62
63 /* do we already have the rDNS? match on it if we do. */
64 if (checklist->dst_rdns) {
65 debugs(28, 3, "aclMatchAcl: '" << AclMatchedName << "' match with stored rDNS '" << checklist->dst_rdns << "' for '" << checklist->request->GetHost() << "'");
66 return data->match(checklist->dst_rdns);
67 }
68
69 /* raw IP without rDNS? look it up and wait for the result */
70 const ipcache_addrs *ia = ipcacheCheckNumeric(checklist->request->GetHost());
71 if (!ia) {
72 /* not a valid IPA */
73 checklist->dst_rdns = xstrdup("invalid");
74 return 0;
75 }
76
77 checklist->dst_addr = ia->in_addrs[0];
78 const char *fqdn = fqdncache_gethostbyaddr(checklist->dst_addr, FQDN_LOOKUP_IF_MISS);
79
80 if (fqdn) {
81 checklist->dst_rdns = xstrdup(fqdn);
82 return data->match(fqdn);
83 } else if (!checklist->destinationDomainChecked()) {
84 /* FIXME: Using AclMatchedName here is not OO correct. Should find a way to the current acl */
85 debugs(28, 3, "aclMatchAcl: Can't yet compare '" << AclMatchedName << "' ACL for '" << checklist->request->GetHost() << "'");
86 if (checklist->goAsync(DestinationDomainLookup::Instance()))
87 return -1;
88 // else fall through to "none" match, hiding the lookup failure (XXX)
89 }
90
91 return data->match("none");
92 }
93
94 ACLDestinationDomainStrategy *
95 ACLDestinationDomainStrategy::Instance()
96 {
97 return &Instance_;
98 }
99
100 ACLDestinationDomainStrategy ACLDestinationDomainStrategy::Instance_;
101