2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 28 Access Control */
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"
19 DestinationDomainLookup
DestinationDomainLookup::instance_
;
21 DestinationDomainLookup
*
22 DestinationDomainLookup::Instance()
28 DestinationDomainLookup::checkForAsync(ACLChecklist
*cl
) const
30 ACLFilledChecklist
*checklist
= Filled(cl
);
31 fqdncache_nbgethostbyaddr(checklist
->dst_addr
, LookupDone
, checklist
);
35 DestinationDomainLookup::LookupDone(const char *, const Dns::LookupDetails
&details
, void *data
)
37 ACLFilledChecklist
*checklist
= Filled((ACLChecklist
*)data
);
38 checklist
->markDestinationDomainChecked();
39 checklist
->request
->recordLookup(details
);
40 checklist
->resumeNonBlockingCheck(DestinationDomainLookup::Instance());
43 /* ACLDestinationDomainStrategy */
46 ACLDestinationDomainStrategy::options()
48 static const Acl::BooleanOption LookupBanFlag
;
49 static const Acl::Options MyOptions
= { { "-n", &LookupBanFlag
} };
50 LookupBanFlag
.linkWith(&lookupBanned
);
55 ACLDestinationDomainStrategy::match (ACLData
<MatchType
> * &data
, ACLFilledChecklist
*checklist
)
57 assert(checklist
!= NULL
&& checklist
->request
!= NULL
);
59 if (data
->match(checklist
->request
->url
.host())) {
64 debugs(28, 3, "No-lookup DNS ACL '" << AclMatchedName
<< "' for " << checklist
->request
->url
.host());
68 /* numeric IPA? no, trust the above result. */
69 if (!checklist
->request
->url
.hostIsNumeric()) {
73 /* do we already have the rDNS? match on it if we do. */
74 if (checklist
->dst_rdns
) {
75 debugs(28, 3, "'" << AclMatchedName
<< "' match with stored rDNS '" << checklist
->dst_rdns
<< "' for " << checklist
->request
->url
.host());
76 return data
->match(checklist
->dst_rdns
);
79 /* raw IP without rDNS? look it up and wait for the result */
80 if (!checklist
->dst_addr
.fromHost(checklist
->request
->url
.host())) {
82 checklist
->dst_rdns
= xstrdup("invalid");
86 const char *fqdn
= fqdncache_gethostbyaddr(checklist
->dst_addr
, FQDN_LOOKUP_IF_MISS
);
89 checklist
->dst_rdns
= xstrdup(fqdn
);
90 return data
->match(fqdn
);
91 } else if (!checklist
->destinationDomainChecked()) {
92 /* FIXME: Using AclMatchedName here is not OO correct. Should find a way to the current acl */
93 debugs(28, 3, "Can't yet compare '" << AclMatchedName
<< "' ACL for " << checklist
->request
->url
.host());
94 if (checklist
->goAsync(DestinationDomainLookup::Instance()))
96 // else fall through to "none" match, hiding the lookup failure (XXX)
99 return data
->match("none");