]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/Checklist.h
author: Alex Rousskov <rousskov@measurement-factory.com>, Christos Tsantilas <chtsant...
[thirdparty/squid.git] / src / acl / Checklist.h
1 /*
2 * $Id$
3 *
4 *
5 * SQUID Web Proxy Cache http://www.squid-cache.org/
6 * ----------------------------------------------------------
7 *
8 * Squid is the result of efforts by numerous individuals from
9 * the Internet community; see the CONTRIBUTORS file for full
10 * details. Many organizations have provided support for Squid's
11 * development; see the SPONSORS file for full details. Squid is
12 * Copyrighted (C) 2001 by the Regents of the University of
13 * California; see the COPYRIGHT file for full details. Squid
14 * incorporates software developed and/or copyrighted by other
15 * sources; see the CREDITS file for full details.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
30 *
31 */
32
33 #ifndef SQUID_ACLCHECKLIST_H
34 #define SQUID_ACLCHECKLIST_H
35
36 #include "acl/Acl.h"
37
38 /// ACL checklist callback
39 typedef void ACLCB(allow_t, void *);
40
41 /** \ingroup ACLAPI
42 Base class for maintaining Squid and transaction state for access checks.
43 Provides basic ACL checking methods. Its only child, ACLFilledChecklist,
44 keeps the actual state data. The split is necessary to avoid exposing
45 all ACL-related code to virtually Squid data types. */
46 class ACLChecklist
47 {
48
49 public:
50
51 /**
52 * State class.
53 * This abstract class defines the behaviour of
54 * async lookups - which can vary for different ACL types.
55 * Today, every state object must be a singleton.
56 * See NULLState for an example.
57 *
58 \note *no* state should be stored in the state object,
59 * they are used to change the behaviour of the checklist, not
60 * to hold information. If you need to store information in the
61 * state object, consider subclassing ACLChecklist, converting it
62 * to a composite, or changing the state objects from singletons to
63 * refcounted objects.
64 */
65
66 class AsyncState
67 {
68
69 public:
70 virtual void checkForAsync(ACLChecklist *) const = 0;
71 virtual ~AsyncState() {}
72
73 protected:
74 void changeState (ACLChecklist *, AsyncState *) const;
75 };
76
77 class NullState : public AsyncState
78 {
79
80 public:
81 static NullState *Instance();
82 virtual void checkForAsync(ACLChecklist *) const;
83 virtual ~NullState() {}
84
85 private:
86 static NullState _instance;
87 };
88
89
90 public:
91 ACLChecklist();
92 virtual ~ACLChecklist();
93
94 /**
95 * Start a non-blocking (async) check for a list of allow/deny rules.
96 * Each rule comes with a list of ACLs.
97 *
98 * The callback specified will be called with the result of the check.
99 *
100 * The first rule where all ACLs match wins. If there is such a rule,
101 * the result becomes that rule keyword (ACCESS_ALLOWED or ACCESS_DENIED).
102 *
103 * If there are rules but all ACL lists mismatch, an implicit rule is used.
104 * Its result is the negation of the keyword of the last seen rule.
105 *
106 * Some ACLs may stop the check prematurely by setting an exceptional
107 * check result (e.g., ACCESS_AUTH_REQUIRED) instead of declaring a
108 * match or mismatch.
109 *
110 * If there are no rules to check at all, the result becomes ACCESS_DUNNO.
111 * Calling this method with no rules to check wastes a lot of CPU cycles
112 * and will result in a DBG_CRITICAL debugging message.
113 */
114 void nonBlockingCheck(ACLCB * callback, void *callback_data);
115
116 /**
117 * Perform a blocking (immediate) check for a list of allow/deny rules.
118 * Each rule comes with a list of ACLs.
119 *
120 * The first rule where all ACLs match wins. If there is such a rule,
121 * the result becomes that rule keyword (ACCESS_ALLOWED or ACCESS_DENIED).
122 *
123 * If there are rules but all ACL lists mismatch, an implicit rule is used
124 * Its result is the negation of the keyword of the last seen rule.
125 *
126 * Some ACLs may stop the check prematurely by setting an exceptional
127 * check result (e.g., ACCESS_AUTH_REQUIRED) instead of declaring a
128 * match or mismatch.
129 *
130 * Some ACLs may require an async lookup which is prohibited by this
131 * method. In this case, the exceptional check result of ACCESS_DUNNO is
132 * immediately returned.
133 *
134 * If there are no rules to check at all, the result becomes ACCESS_DUNNO.
135 */
136 allow_t const & fastCheck();
137
138 /**
139 * Perform a blocking (immediate) check whether a list of ACLs matches.
140 * This method is meant to be used with squid.conf ACL-driven options that
141 * lack allow/deny keywords and are tested one ACL list at a time. Whether
142 * the checks for other occurrences of the same option continue after this
143 * call is up to the caller and option semantics.
144 *
145 * If all ACLs match, the result becomes ACCESS_ALLOWED.
146 *
147 * If all ACLs mismatch, the result becomes ACCESS_DENIED.
148 *
149 * Some ACLs may stop the check prematurely by setting an exceptional
150 * check result (e.g., ACCESS_AUTH_REQUIRED) instead of declaring a
151 * match or mismatch.
152 *
153 * Some ACLs may require an async lookup which is prohibited by this
154 * method. In this case, the exceptional check result of ACCESS_DUNNO is
155 * immediately returned.
156 *
157 * If there are no ACLs to check at all, the result becomes ACCESS_ALLOWED.
158 */
159 allow_t const & fastCheck(const ACLList * list);
160
161 // whether the last checked ACL of the current rule needs
162 // an async operation to determine whether there was a match
163 bool asyncNeeded() const;
164 bool asyncInProgress() const;
165 void asyncInProgress(bool const);
166
167 /// whether markFinished() was called
168 bool finished() const;
169 /// called when no more ACLs should be checked; sets the final answer and
170 /// prints a debugging message explaining the reason for that answer
171 void markFinished(const allow_t &newAnswer, const char *reason);
172
173 const allow_t &currentAnswer() const { return allow_; }
174
175 void changeState(AsyncState *);
176 AsyncState *asyncState() const;
177
178 // XXX: ACLs that need request or reply have to use ACLFilledChecklist and
179 // should do their own checks so that we do not have to povide these two
180 // for ACL::checklistMatches to use
181 virtual bool hasRequest() const = 0;
182 virtual bool hasReply() const = 0;
183
184 private:
185 /// Calls non-blocking check callback with the answer and destroys self.
186 void checkCallback(allow_t answer);
187
188 void checkAccessList();
189 void checkForAsync();
190
191 public:
192 const acl_access *accessList;
193
194 ACLCB *callback;
195 void *callback_data;
196
197 /**
198 * Performs non-blocking check starting with the current rule.
199 * Used by nonBlockingCheck() to initiate the checks and by
200 * async operation callbacks to resume checks after the async
201 * operation updates the current Squid state. See nonBlockingCheck()
202 * for details on final result determination.
203 */
204 void matchNonBlocking();
205
206 private: /* internal methods */
207 /// possible outcomes when trying to match a single ACL node in a list
208 typedef enum { nmrMatch, nmrMismatch, nmrFinished, nmrNeedsAsync }
209 NodeMatchingResult;
210
211 /// prepare for checking ACLs; called once per check
212 void preCheck(const char *what);
213 bool matchAclList(const ACLList * list, bool const fast);
214 bool matchNodes(const ACLList * head, bool const fast);
215 NodeMatchingResult matchNode(const ACLList &node, bool const fast);
216 void calcImplicitAnswer(const allow_t &lastSeenAction);
217
218 bool async_;
219 bool finished_;
220 allow_t allow_;
221 AsyncState *state_;
222
223 bool checking_;
224 bool checking() const;
225 void checking (bool const);
226
227 bool callerGone();
228 };
229
230 #endif /* SQUID_ACLCHECKLIST_H */