From: robertc <> Date: Tue, 28 Jan 2003 08:29:32 +0000 (+0000) Subject: Summary: Make aclCheck_t a class (ACLChecklist), and hopefully fix bug 516. X-Git-Tag: SQUID_3_0_PRE1~420 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4fb35c3c3fe435245e660a48f841a4853e5c0eba;p=thirdparty%2Fsquid.git Summary: Make aclCheck_t a class (ACLChecklist), and hopefully fix bug 516. Keywords: Extract aclCheck_t from structs.h to ACLChecklist.h, and rename to ACLChecklist. Add ACLChecklist to the SQUID_sources to have it distributed. Remove aclCheck_t as a global cbdata, instead use per class cbdata. Create constructor and destructors for ACLChecklist. Remove all aclCheck_t memset's. Make aclCheckCallback into ACLChecklist::checkCallback. In clientCheckNoCache, cbdatareference the context before handing off to aclNBCheck. In clientCheckNoCacheDone, check that http is still valid before using it. --- diff --git a/src/ACLChecklist.h b/src/ACLChecklist.h new file mode 100644 index 0000000000..5055a23533 --- /dev/null +++ b/src/ACLChecklist.h @@ -0,0 +1,72 @@ + +/* + * $Id: ACLChecklist.h,v 1.1 2003/01/28 01:29:32 robertc Exp $ + * + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#ifndef SQUID_ACLCHECKLIST_H +#define SQUID_ACLCHECKLIST_H + +#include "typedefs.h" + +class ACLChecklist { + public: + void *operator new(size_t); + void operator delete(void *); + void deleteSelf() const; + + ACLChecklist(); + ~ACLChecklist(); + + void checkCallback(allow_t answer); + + const acl_access *accessList; + struct in_addr src_addr; + struct in_addr dst_addr; + struct in_addr my_addr; + unsigned short my_port; + request_t *request; + /* for acls that look at reply data */ + HttpReply *reply; + ConnStateData *conn; /* hack for ident and NTLM */ + char rfc931[USER_IDENT_SZ]; + auth_user_request_t *auth_user_request; + acl_lookup_state state[ACL_ENUM_MAX]; +#if SQUID_SNMP + char *snmp_community; +#endif + PF *callback; + void *callback_data; + external_acl_entry *extacl_entry; +private: + CBDATA_CLASS(ACLChecklist); +}; + +#endif /* SQUID_ACLCHECKLIST_H */ diff --git a/src/HttpHeaderTools.cc b/src/HttpHeaderTools.cc index 49610fd800..33995bddf1 100644 --- a/src/HttpHeaderTools.cc +++ b/src/HttpHeaderTools.cc @@ -1,6 +1,6 @@ /* - * $Id: HttpHeaderTools.cc,v 1.35 2003/01/23 00:37:12 robertc Exp $ + * $Id: HttpHeaderTools.cc,v 1.36 2003/01/28 01:29:32 robertc Exp $ * * DEBUG: section 66 HTTP Header Tools * AUTHOR: Alex Rousskov @@ -411,7 +411,7 @@ httpHdrMangle(HttpHeaderEntry * e, request_t * request) /* check with anonymizer tables */ header_mangler *hm; - aclCheck_t *checklist; + ACLChecklist *checklist; assert(e); hm = &Config.header_access[e->id]; checklist = aclChecklistCreate(hm->access_list, request, NULL); diff --git a/src/HttpReply.cc b/src/HttpReply.cc index b0d12b767c..fe76f1e339 100644 --- a/src/HttpReply.cc +++ b/src/HttpReply.cc @@ -1,6 +1,6 @@ /* - * $Id: HttpReply.cc,v 1.51 2003/01/23 00:37:13 robertc Exp $ + * $Id: HttpReply.cc,v 1.52 2003/01/28 01:29:32 robertc Exp $ * * DEBUG: section 58 HTTP Reply (Response) * AUTHOR: Alex Rousskov @@ -38,7 +38,7 @@ #include "Store.h" #include "HttpHeader.h" #include "HttpHdrContRange.h" - +#include "ACLChecklist.h" /* local constants */ @@ -550,7 +550,7 @@ void httpReplyBodyBuildSize(request_t * request, HttpReply * reply, dlink_list * bodylist) { body_size *bs; - aclCheck_t *checklist; + ACLChecklist *checklist; bs = (body_size *) bodylist->head; while (bs) { checklist = aclChecklistCreate(bs->access_list, request, NULL); diff --git a/src/Makefile.am b/src/Makefile.am index 593e7d070f..1cc6c818d1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.am,v 1.51 2003/01/27 08:28:29 robertc Exp $ +# $Id: Makefile.am,v 1.52 2003/01/28 01:29:32 robertc Exp $ # # Uncomment and customize the following to suit your needs: # @@ -122,6 +122,7 @@ EXTRA_squid_SOURCES = \ squid_SOURCES = \ access_log.cc \ acl.cc \ + ACLChecklist.h \ asn.cc \ authenticate.cc \ authenticate.h \ @@ -392,6 +393,7 @@ ufsdump_SOURCES = debug.cc \ mem.cc \ mem_node.cc \ mem_node.h \ + Mem.h \ MemBuf.cc \ MemObject.cc \ MemObject.h \ diff --git a/src/acl.cc b/src/acl.cc index 55040fe546..a599c013a8 100644 --- a/src/acl.cc +++ b/src/acl.cc @@ -1,5 +1,5 @@ /* - * $Id: acl.cc,v 1.296 2003/01/24 09:07:19 robertc Exp $ + * $Id: acl.cc,v 1.297 2003/01/28 01:29:33 robertc Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -33,6 +33,7 @@ */ #include "squid.h" +#include "ACLChecklist.h" #include "splay.h" #include "HttpRequest.h" #include "authenticate.h" @@ -51,10 +52,10 @@ static void aclParseTimeSpec(void *curlist); static void aclParseIntRange(void *curlist); static void aclDestroyTimeList(acl_time_data * data); static void aclDestroyIntRange(intrange *); -static void aclLookupProxyAuthStart(aclCheck_t * checklist); +static void aclLookupProxyAuthStart(ACLChecklist * checklist); static void aclLookupProxyAuthDone(void *data, char *result); static struct _acl *aclFindByName(const char *name); -static int aclMatchAcl(struct _acl *, aclCheck_t *); +static int aclMatchAcl(struct _acl *, ACLChecklist *); static int aclMatchTime(acl_time_data * data, time_t when); static int aclMatchUser(void *proxyauth_acl, char const *user); static int aclMatchIp(void *dataptr, struct in_addr c); @@ -69,8 +70,7 @@ static wordlist *aclDumpUserMaxIP(void *data); static int aclMatchUserMaxIP(void *, auth_user_request_t *, struct in_addr); static squid_acl aclStrToType(const char *s); static int decode_addr(const char *, struct in_addr *, struct in_addr *); -static void aclCheck(aclCheck_t * checklist); -static void aclCheckCallback(aclCheck_t * checklist, allow_t answer); +static void aclCheck(ACLChecklist * checklist); #if USE_IDENT static IDCB aclLookupIdentDone; #endif @@ -106,8 +106,8 @@ static SPLAYWALKEE aclDumpArpListWalkee; static int aclCacheMatchAcl(dlink_list * cache, squid_acl acltype, void *data, char const *MatchParam); #if USE_SSL static void aclParseCertList(void *curlist); -static int aclMatchUserCert(void *data, aclCheck_t *); -static int aclMatchCACert(void *data, aclCheck_t *); +static int aclMatchUserCert(void *data, ACLChecklist *); +static int aclMatchCACert(void *data, ACLChecklist *); static wordlist *aclDumpCertList(void *data); static void aclDestroyCertList(void *data); #endif @@ -717,7 +717,7 @@ aclParseCertList(void *curlist) } static int -aclMatchUserCert(void *data, aclCheck_t * checklist) +aclMatchUserCert(void *data, ACLChecklist * checklist) { acl_cert_data *cert_data = (acl_cert_data *)data; const char *value; @@ -733,7 +733,7 @@ aclMatchUserCert(void *data, aclCheck_t * checklist) } static int -aclMatchCACert(void *data, aclCheck_t * checklist) +aclMatchCACert(void *data, ACLChecklist * checklist) { acl_cert_data *cert_data = (acl_cert_data *)data; const char *value; @@ -1285,7 +1285,7 @@ aclCacheMatchFlush(dlink_list * cache) */ static int aclMatchProxyAuth(void *data, auth_user_request_t * auth_user_request, - aclCheck_t * checklist, squid_acl acltype) + ACLChecklist * checklist, squid_acl acltype) { /* checklist is used to register user name when identified, nothing else */ /* General program flow in proxy_auth acls @@ -1402,7 +1402,7 @@ aclMatchUserMaxIP(void *data, auth_user_request_t * auth_user_request, } static void -aclLookupProxyAuthStart(aclCheck_t * checklist) +aclLookupProxyAuthStart(ACLChecklist * checklist) { auth_user_request_t *auth_user_request; /* make sure someone created auth_user_request for us */ @@ -1500,7 +1500,7 @@ aclMatchWordList(wordlist * w, const char *word) #endif int -aclAuthenticated(aclCheck_t * checklist) +aclAuthenticated(ACLChecklist * checklist) { request_t *r = checklist->request; http_hdr_type headertype; @@ -1545,7 +1545,7 @@ aclAuthenticated(aclCheck_t * checklist) } static int -aclMatchAcl(acl * ae, aclCheck_t * checklist) +aclMatchAcl(acl * ae, ACLChecklist * checklist) { request_t *r = checklist->request; const ipcache_addrs *ia = NULL; @@ -1806,7 +1806,7 @@ aclMatchAcl(acl * ae, aclCheck_t * checklist) } int -aclMatchAclList(const acl_list * list, aclCheck_t * checklist) +aclMatchAclList(const acl_list * list, ACLChecklist * checklist) { PROF_start(aclMatchAclList); while (list) { @@ -1826,7 +1826,7 @@ aclMatchAclList(const acl_list * list, aclCheck_t * checklist) } static void -aclCheckCleanup(aclCheck_t * checklist) +aclCheckCleanup(ACLChecklist * checklist) { /* Cleanup temporary stuff used by the ACL checking */ if (checklist->extacl_entry) { @@ -1834,8 +1834,11 @@ aclCheckCleanup(aclCheck_t * checklist) } } +/* Warning: do not cbdata lock checklist here - it + * may be static or on the stack + */ int -aclCheckFast(const acl_access * A, aclCheck_t * checklist) +aclCheckFast(const acl_access * A, ACLChecklist * checklist) { allow_t allow = ACCESS_DENIED; PROF_start(aclCheckFast); @@ -1856,7 +1859,7 @@ aclCheckFast(const acl_access * A, aclCheck_t * checklist) } static void -aclCheck(aclCheck_t * checklist) +aclCheck(ACLChecklist * checklist) { allow_t allow = ACCESS_DENIED; const acl_access *A; @@ -1948,7 +1951,7 @@ aclCheck(aclCheck_t * checklist) if (match) { debug(28, 3) ("aclCheck: match found, returning %d\n", allow); cbdataReferenceDone(checklist->accessList); /* A */ - aclCheckCallback(checklist, allow); + checklist->checkCallback(allow); return; } /* @@ -1958,11 +1961,11 @@ aclCheck(aclCheck_t * checklist) cbdataReferenceDone(A); } debug(28, 3) ("aclCheck: NO match found, returning %d\n", allow != ACCESS_DENIED ? ACCESS_DENIED : ACCESS_ALLOWED); - aclCheckCallback(checklist, allow != ACCESS_DENIED ? ACCESS_DENIED : ACCESS_ALLOWED); + checklist->checkCallback(allow != ACCESS_DENIED ? ACCESS_DENIED : ACCESS_ALLOWED); } void -aclChecklistFree(aclCheck_t * checklist) +aclChecklistFree(ACLChecklist * checklist) { if (checklist->request) requestUnlink(checklist->request); @@ -1970,37 +1973,38 @@ aclChecklistFree(aclCheck_t * checklist) cbdataReferenceDone(checklist->conn); cbdataReferenceDone(checklist->accessList); aclCheckCleanup(checklist); - cbdataFree(checklist); + delete checklist; } -static void -aclCheckCallback(aclCheck_t * checklist, allow_t answer) -{ - PF *callback; - void *cbdata; - debug(28, 3) ("aclCheckCallback: answer=%d\n", answer); - /* During reconfigure, we can end up not finishing call sequences into the auth code */ - if (checklist->auth_user_request) { +void +ACLChecklist::checkCallback(allow_t answer) +{ + PF *callback_; + void *cbdata_; + debug(28, 3) ("ACLChecklist::checkCallback: answer=%d\n", answer); + /* During reconfigure, we can end up not finishing call + * sequences into the auth code */ + if (auth_user_request) { /* the checklist lock */ - authenticateAuthUserRequestUnlock(checklist->auth_user_request); + authenticateAuthUserRequestUnlock(auth_user_request); /* it might have been connection based */ - assert(checklist->conn); - checklist->conn->auth_user_request = NULL; - checklist->conn->auth_type = AUTH_BROKEN; - checklist->auth_user_request = NULL; + assert(conn); + conn->auth_user_request = NULL; + conn->auth_type = AUTH_BROKEN; + auth_user_request = NULL; } - callback = checklist->callback; - checklist->callback = NULL; - if (cbdataReferenceValidDone(checklist->callback_data, &cbdata)) - callback(answer, cbdata); - aclChecklistFree(checklist); + callback_ = callback; + callback = NULL; + if (cbdataReferenceValidDone(callback_data, &cbdata_)) + callback_(answer, cbdata_); + aclChecklistFree(this); } #if USE_IDENT static void aclLookupIdentDone(const char *ident, void *data) { - aclCheck_t *checklist = (aclCheck_t *)data; + ACLChecklist *checklist = (ACLChecklist *)data; if (ident) { xstrncpy(checklist->rfc931, ident, USER_IDENT_SZ); #if DONT @@ -2022,7 +2026,7 @@ aclLookupIdentDone(const char *ident, void *data) static void aclLookupDstIPDone(const ipcache_addrs * ia, void *data) { - aclCheck_t *checklist = (aclCheck_t *)data; + ACLChecklist *checklist = (ACLChecklist *)data; checklist->state[ACL_DST_IP] = ACL_LOOKUP_DONE; aclCheck(checklist); } @@ -2030,7 +2034,7 @@ aclLookupDstIPDone(const ipcache_addrs * ia, void *data) static void aclLookupDstIPforASNDone(const ipcache_addrs * ia, void *data) { - aclCheck_t *checklist = (aclCheck_t *)data; + ACLChecklist *checklist = (ACLChecklist *)data; checklist->state[ACL_DST_ASN] = ACL_LOOKUP_DONE; aclCheck(checklist); } @@ -2038,7 +2042,7 @@ aclLookupDstIPforASNDone(const ipcache_addrs * ia, void *data) static void aclLookupSrcFQDNDone(const char *fqdn, void *data) { - aclCheck_t *checklist = (aclCheck_t *)data; + ACLChecklist *checklist = (ACLChecklist *)data; checklist->state[ACL_SRC_DOMAIN] = ACL_LOOKUP_DONE; aclCheck(checklist); } @@ -2046,7 +2050,7 @@ aclLookupSrcFQDNDone(const char *fqdn, void *data) static void aclLookupDstFQDNDone(const char *fqdn, void *data) { - aclCheck_t *checklist = (aclCheck_t *)data; + ACLChecklist *checklist = (ACLChecklist *)data; checklist->state[ACL_DST_DOMAIN] = ACL_LOOKUP_DONE; aclCheck(checklist); } @@ -2054,7 +2058,7 @@ aclLookupDstFQDNDone(const char *fqdn, void *data) static void aclLookupProxyAuthDone(void *data, char *result) { - aclCheck_t *checklist = (aclCheck_t *)data; + ACLChecklist *checklist = (ACLChecklist *)data; checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_DONE; if (result != NULL) fatal("AclLookupProxyAuthDone: Old code floating around somewhere.\nMake clean and if that doesn't work, report a bug to the squid developers.\n"); @@ -2075,36 +2079,87 @@ aclLookupProxyAuthDone(void *data, char *result) static void aclLookupExternalDone(void *data, void *result) { - aclCheck_t *checklist = (aclCheck_t *)data; + ACLChecklist *checklist = (ACLChecklist *)data; checklist->state[ACL_EXTERNAL] = ACL_LOOKUP_DONE; checklist->extacl_entry = cbdataReference((external_acl_entry *)result); aclCheck(checklist); } +CBDATA_CLASS_INIT(ACLChecklist); + +void * +ACLChecklist::operator new (size_t size) +{ + assert (size == sizeof(ACLChecklist)); + CBDATA_INIT_TYPE(ACLChecklist); + ACLChecklist *result = cbdataAlloc(ACLChecklist); + /* Mark result as being owned - we want the refcounter to do the delete + * call */ + cbdataReference(result); + return result; +} + +void +ACLChecklist::operator delete (void *address) +{ + ACLChecklist *t = static_cast(address); + cbdataFree(address); + /* And allow the memory to be freed */ + cbdataReferenceDone (t); +} + +void +ACLChecklist::deleteSelf() const +{ + delete this; +} + +ACLChecklist::ACLChecklist() : accessList (NULL), my_port (0), request (NULL), + reply (NULL), + conn (NULL), + auth_user_request (NULL) +#if SQUID_SNMP + ,snmp_community(NULL) +#endif + , callback (NULL), + callback_data (NULL), + extacl_entry (NULL) +{ + memset (&src_addr, '\0', sizeof (struct in_addr)); + memset (&dst_addr, '\0', sizeof (struct in_addr)); + memset (&my_addr, '\0', sizeof (struct in_addr)); + rfc931[0] = '\0'; + memset (&state, '\0', sizeof (state)); +} + +ACLChecklist::~ACLChecklist() +{ +} + /* - * Any aclCheck_t created by aclChecklistCreate() must eventually be + * Any ACLChecklist created by aclChecklistCreate() must eventually be * freed by aclChecklistFree(). There are two common cases: * - * A) Using aclCheckFast(): The caller creates the aclCheck_t using + * A) Using aclCheckFast(): The caller creates the ACLChecklist using * aclChecklistCreate(), checks it using aclCheckFast(), and frees it * using aclChecklistFree(). * * B) Using aclNBCheck() and callbacks: The caller creates the - * aclCheck_t using aclChecklistCreate(), and passes it to - * aclNBCheck(). Control eventually passes to aclCheckCallback(), + * ACLChecklist using aclChecklistCreate(), and passes it to + * aclNBCheck(). Control eventually passes to ACLChecklist::checkCallback(), * which will invoke the callback function as requested by the * original caller of aclNBCheck(). This callback function must * *not* invoke aclChecklistFree(). After the callback function - * returns, aclCheckCallback() will free the aclCheck_t using + * returns, ACLChecklist::checkCallback() will free the ACLChecklist using * aclChecklistFree(). */ -aclCheck_t * + +ACLChecklist * aclChecklistCreate(const acl_access * A, request_t * request, const char *ident) { int i; - aclCheck_t *checklist; - checklist = cbdataAlloc(aclCheck_t); + ACLChecklist *checklist = new ACLChecklist; checklist->accessList = cbdataReference(A); if (request != NULL) { checklist->request = requestLink(request); @@ -2123,7 +2178,7 @@ aclChecklistCreate(const acl_access * A, request_t * request, const char *ident) } void -aclNBCheck(aclCheck_t * checklist, PF * callback, void *callback_data) +aclNBCheck(ACLChecklist * checklist, PF * callback, void *callback_data) { checklist->callback = callback; checklist->callback_data = cbdataReference(callback_data); diff --git a/src/cbdata.cc b/src/cbdata.cc index f092eecc2b..528e7ec6ea 100644 --- a/src/cbdata.cc +++ b/src/cbdata.cc @@ -1,6 +1,6 @@ /* - * $Id: cbdata.cc,v 1.51 2003/01/23 00:37:17 robertc Exp $ + * $Id: cbdata.cc,v 1.52 2003/01/28 01:29:33 robertc Exp $ * * DEBUG: section 45 Callback Data Registry * ORIGINAL AUTHOR: Duane Wessels @@ -172,7 +172,6 @@ cbdataInit(void) * most of these should be moved out to their respective module. */ CREATE_CBDATA(acl_access); - CREATE_CBDATA(aclCheck_t); CREATE_CBDATA(ConnStateData); CREATE_CBDATA(ErrorState); CREATE_CBDATA(FwdState); diff --git a/src/client_side.cc b/src/client_side.cc index c868616c67..acfed42540 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.614 2003/01/27 08:36:22 hno Exp $ + * $Id: client_side.cc,v 1.615 2003/01/28 01:29:33 robertc Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -66,6 +66,7 @@ #include "MemObject.h" #include "fde.h" #include "client_side_request.h" +#include "ACLChecklist.h" #if LINGERING_CLOSE #define comm_close comm_lingering_close @@ -2222,7 +2223,7 @@ httpAccept(int sock, int newfd, struct sockaddr_in *me, struct sockaddr_in *peer int *N = &incoming_sockets_accepted; ConnStateData *connState = NULL; #if USE_IDENT - static aclCheck_t identChecklist; + static ACLChecklist identChecklist; #endif if (flag == COMM_ERR_CLOSING) { @@ -2326,7 +2327,7 @@ httpsAccept(int sock, int newfd, struct sockaddr_in *me, struct sockaddr_in *pee SSL *ssl; int ssl_error; #if USE_IDENT - static aclCheck_t identChecklist; + static ACLChecklist identChecklist; #endif if (flag == COMM_ERR_CLOSING) { @@ -2525,10 +2526,10 @@ varyEvaluateMatch(StoreEntry * entry, request_t * request) } } -aclCheck_t * +ACLChecklist * clientAclChecklistCreate(const acl_access * acl, const clientHttpRequest * http) { - aclCheck_t *ch; + ACLChecklist *ch; ConnStateData *conn = http->conn; ch = aclChecklistCreate(acl, http->request, conn ? conn->rfc931 : dash_str); @@ -2544,7 +2545,7 @@ clientAclChecklistCreate(const acl_access * acl, const clientHttpRequest * http) * the server end. */ if (conn) - ch->conn = cbdataReference(conn); /* unreferenced in acl.c */ + ch->conn = cbdataReference(conn); /* unreferenced in acl.cc */ return ch; } diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index a5cb1c3fa9..bbe5687c9e 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side_reply.cc,v 1.31 2003/01/23 00:37:18 robertc Exp $ + * $Id: client_side_reply.cc,v 1.32 2003/01/28 01:29:34 robertc Exp $ * * DEBUG: section 88 Client-side Reply Routines * AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c) @@ -43,6 +43,7 @@ #include "authenticate.h" #include "MemObject.h" #include "client_side_request.h" +#include "ACLChecklist.h" static STCB clientHandleIMSReply; static STCB clientSendMoreData; @@ -1852,7 +1853,7 @@ clientReplyContext::sendMoreData (StoreIOBuffer result) debug(88,3) ("clientSendMoreData: Appending %d bytes after %d bytes of headers\n", (int) body_size, rep->hdr_sz); - aclCheck_t *ch = clientAclChecklistCreate(Config.accessList.reply, http); + ACLChecklist *ch = clientAclChecklistCreate(Config.accessList.reply, http); ch->reply = rep; rv = aclCheckFast(Config.accessList.reply, ch); aclChecklistFree(ch); diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 783e5f4c19..2b6de0c076 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side_request.cc,v 1.9 2003/01/23 00:37:18 robertc Exp $ + * $Id: client_side_request.cc,v 1.10 2003/01/28 01:29:34 robertc Exp $ * * DEBUG: section 85 Client-side Request Routines * AUTHOR: Robert Collins (Originally Duane Wessels in client_side.c) @@ -54,7 +54,7 @@ static const char *const crlf = "\r\n"; typedef struct _clientRequestContext { - aclCheck_t *acl_checklist; /* need ptr back so we can unreg if needed */ + ACLChecklist *acl_checklist; /* need ptr back so we can unreg if needed */ int redirect_state; clientHttpRequest *http; } clientRequestContext; @@ -649,20 +649,28 @@ clientCheckNoCache(clientRequestContext * context) if (Config.accessList.noCache && http->request->flags.cachable) { context->acl_checklist = clientAclChecklistCreate(Config.accessList.noCache, http); - aclNBCheck(context->acl_checklist, clientCheckNoCacheDone, context); + aclNBCheck(context->acl_checklist, clientCheckNoCacheDone, cbdataReference(context)); } else { - clientCheckNoCacheDone(http->request->flags.cachable, context); + clientCheckNoCacheDone(http->request->flags.cachable, cbdataReference(context)); } } void clientCheckNoCacheDone(int answer, void *data) { - clientRequestContext *context = (clientRequestContext *)data; - clientHttpRequest *http = context->http; - http->request->flags.cachable = answer; + void *temp; + bool valid = cbdataReferenceValidDone(data, &temp); + assert (valid); + clientRequestContext *context = (clientRequestContext *)temp; + context->acl_checklist = NULL; + clientHttpRequest *http = context->http; cbdataFree(context); + + if (!cbdataReferenceValid (http)) + return; + + http->request->flags.cachable = answer; clientProcessRequest(http); } diff --git a/src/client_side_request.h b/src/client_side_request.h index 07c8f638f5..d0f04ded90 100644 --- a/src/client_side_request.h +++ b/src/client_side_request.h @@ -1,6 +1,6 @@ /* - * $Id: client_side_request.h,v 1.3 2003/01/23 00:59:44 robertc Exp $ + * $Id: client_side_request.h,v 1.4 2003/01/28 01:29:34 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -97,7 +97,7 @@ private: /* client http based routines */ SQUIDCEXTERN char *clientConstructTraceEcho(clientHttpRequest *); -SQUIDCEXTERN aclCheck_t *clientAclChecklistCreate(const acl_access * acl, const clientHttpRequest * http); +SQUIDCEXTERN ACLChecklist *clientAclChecklistCreate(const acl_access * acl, const clientHttpRequest * http); SQUIDCEXTERN void *clientReplyNewContext(clientHttpRequest *); SQUIDCEXTERN int clientHttpRequestStatus(int fd, clientHttpRequest const *http); diff --git a/src/delay_pools.cc b/src/delay_pools.cc index f1254d0c1d..1ddff3deda 100644 --- a/src/delay_pools.cc +++ b/src/delay_pools.cc @@ -1,6 +1,6 @@ /* - * $Id: delay_pools.cc,v 1.30 2003/01/23 00:37:19 robertc Exp $ + * $Id: delay_pools.cc,v 1.31 2003/01/28 01:29:34 robertc Exp $ * * DEBUG: section 77 Delay Pools * AUTHOR: David Luyer @@ -312,7 +312,6 @@ delay_id delayClient(clientHttpRequest * http) { request_t *r; - aclCheck_t ch; int i; int j; unsigned int host; @@ -321,7 +320,7 @@ delayClient(clientHttpRequest * http) assert(http); r = http->request; - memset(&ch, '\0', sizeof(ch)); + ACLChecklist ch; ch.src_addr = r->client_addr; ch.my_addr = r->my_addr; ch.my_port = r->my_port; diff --git a/src/enums.h b/src/enums.h index 8045f95dce..5fdeb4f95a 100644 --- a/src/enums.h +++ b/src/enums.h @@ -1,6 +1,6 @@ /* - * $Id: enums.h,v 1.220 2003/01/27 08:06:57 hno Exp $ + * $Id: enums.h,v 1.221 2003/01/28 01:29:34 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -705,7 +705,6 @@ typedef enum { CBDATA_UNKNOWN = 0, CBDATA_UNDEF = 0, CBDATA_acl_access, - CBDATA_aclCheck_t, CBDATA_ConnStateData, CBDATA_ErrorState, CBDATA_FwdState, diff --git a/src/external_acl.cc b/src/external_acl.cc index 9e56c8cce3..056aa9ff1d 100644 --- a/src/external_acl.cc +++ b/src/external_acl.cc @@ -1,6 +1,6 @@ /* - * $Id: external_acl.cc,v 1.23 2003/01/24 09:07:19 robertc Exp $ + * $Id: external_acl.cc,v 1.24 2003/01/28 01:29:34 robertc Exp $ * * DEBUG: section 82 External ACL * AUTHOR: Henrik Nordstrom, MARA Systems AB @@ -44,6 +44,7 @@ #include "authenticate.h" #include "Store.h" #include "fde.h" +#include "ACLChecklist.h" #ifndef DEFAULT_EXTERNAL_ACL_TTL #define DEFAULT_EXTERNAL_ACL_TTL 1 * 60 * 60 @@ -55,7 +56,7 @@ typedef struct _external_acl_format external_acl_format; typedef struct _external_acl_data external_acl_data; -static char *makeExternalAclKey(aclCheck_t * ch, external_acl_data * acl_data); +static char *makeExternalAclKey(ACLChecklist * ch, external_acl_data * acl_data); static void external_acl_cache_delete(external_acl * def, external_acl_entry * entry); static int external_acl_entry_expired(external_acl * def, external_acl_entry * entry); static void external_acl_cache_touch(external_acl * def, external_acl_entry * entry); @@ -425,7 +426,7 @@ aclDestroyExternal(void **dataptr) } int -aclMatchExternal(void *data, aclCheck_t * ch) +aclMatchExternal(void *data, ACLChecklist * ch) { int result; external_acl_entry *entry; @@ -509,7 +510,7 @@ external_acl_cache_touch(external_acl * def, external_acl_entry * entry) } static char * -makeExternalAclKey(aclCheck_t * ch, external_acl_data * acl_data) +makeExternalAclKey(ACLChecklist * ch, external_acl_data * acl_data) { static MemBuf mb = MemBufNULL; char buf[256]; @@ -780,7 +781,7 @@ externalAclHandleReply(void *data, char *reply) } void -externalAclLookup(aclCheck_t * ch, void *acl_data, EAH * callback, void *callback_data) +externalAclLookup(ACLChecklist * ch, void *acl_data, EAH * callback, void *callback_data) { MemBuf buf; external_acl_data *acl = static_cast(acl_data); diff --git a/src/forward.cc b/src/forward.cc index 6314f4d12b..9f46af2bf6 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -1,6 +1,6 @@ /* - * $Id: forward.cc,v 1.91 2003/01/23 00:37:20 robertc Exp $ + * $Id: forward.cc,v 1.92 2003/01/28 01:29:34 robertc Exp $ * * DEBUG: section 17 Request Forwarding * AUTHOR: Duane Wessels @@ -39,6 +39,7 @@ #include "HttpRequest.h" #include "fde.h" #include "MemObject.h" +#include "ACLChecklist.h" static PSC fwdStartComplete; static void fwdDispatch(FwdState *); @@ -358,7 +359,7 @@ fwdConnectTimeout(int fd, void *data) } static struct in_addr -aclMapAddr(acl_address * head, aclCheck_t * ch) +aclMapAddr(acl_address * head, ACLChecklist * ch) { acl_address *l; struct in_addr addr; @@ -371,7 +372,7 @@ aclMapAddr(acl_address * head, aclCheck_t * ch) } static int -aclMapTOS(acl_tos * head, aclCheck_t * ch) +aclMapTOS(acl_tos * head, ACLChecklist * ch) { acl_tos *l; for (l = head; l; l = l->next) { @@ -384,8 +385,7 @@ aclMapTOS(acl_tos * head, aclCheck_t * ch) struct in_addr getOutgoingAddr(request_t * request) { - aclCheck_t ch; - memset(&ch, '\0', sizeof(aclCheck_t)); + ACLChecklist ch; if (request) { ch.src_addr = request->client_addr; ch.my_addr = request->my_addr; @@ -398,8 +398,7 @@ getOutgoingAddr(request_t * request) unsigned long getOutgoingTOS(request_t * request) { - aclCheck_t ch; - memset(&ch, '\0', sizeof(aclCheck_t)); + ACLChecklist ch; if (request) { ch.src_addr = request->client_addr; ch.my_addr = request->my_addr; @@ -656,7 +655,7 @@ void fwdStart(int fd, StoreEntry * e, request_t * r) { FwdState *fwdState; - aclCheck_t ch; + ACLChecklist ch; int answer; ErrorState *err; /* @@ -668,7 +667,6 @@ fwdStart(int fd, StoreEntry * e, request_t * r) /* * Check if this host is allowed to fetch MISSES from us (miss_access) */ - memset(&ch, '\0', sizeof(aclCheck_t)); ch.src_addr = r->client_addr; ch.my_addr = r->my_addr; ch.my_port = r->my_port; diff --git a/src/http.cc b/src/http.cc index ab4a010393..faa22ba9da 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,6 +1,6 @@ /* - * $Id: http.cc,v 1.404 2003/01/23 00:37:22 robertc Exp $ + * $Id: http.cc,v 1.405 2003/01/28 01:29:34 robertc Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -46,6 +46,7 @@ #include "HttpRequest.h" #include "MemObject.h" #include "HttpHdrContRange.h" +#include "ACLChecklist.h" CBDATA_TYPE(HttpStateData); @@ -1253,10 +1254,9 @@ static void httpSendRequestEntityDone(int fd, void *data) { HttpStateData *httpState = static_cast(data); - aclCheck_t ch; + ACLChecklist ch; debug(11, 5) ("httpSendRequestEntityDone: FD %d\n", fd); - memset(&ch, '\0', sizeof(ch)); ch.request = httpState->request; if (!Config.accessList.brokenPosts) { debug(11, 5) ("httpSendRequestEntityDone: No brokenPosts list\n"); diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 8b39a3f3ee..b61a0f10da 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -1,6 +1,6 @@ /* - * $Id: icp_v2.cc,v 1.74 2003/01/23 00:37:22 robertc Exp $ + * $Id: icp_v2.cc,v 1.75 2003/01/28 01:29:34 robertc Exp $ * * DEBUG: section 12 Internet Cache Protocol * AUTHOR: Duane Wessels @@ -38,6 +38,7 @@ #include "comm.h" #include "ICP.h" #include "HttpRequest.h" +#include "ACLChecklist.h" static void icpLogIcp(struct in_addr, log_type, int, const char *, int); static void icpHandleIcpV2(int, struct sockaddr_in, char *, int); @@ -329,8 +330,7 @@ icpDenyAccess(struct sockaddr_in *from, char *url, int reqnum, int fd) int icpAccessAllowed(struct sockaddr_in *from, request_t * icp_request) { - aclCheck_t checklist; - memset(&checklist, '\0', sizeof(checklist)); + ACLChecklist checklist; checklist.src_addr = from->sin_addr; checklist.my_addr = no_addr; checklist.request = icp_request; diff --git a/src/neighbors.cc b/src/neighbors.cc index a636cf3697..351912f954 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1,6 +1,6 @@ /* - * $Id: neighbors.cc,v 1.309 2003/01/23 00:37:23 robertc Exp $ + * $Id: neighbors.cc,v 1.310 2003/01/28 01:29:34 robertc Exp $ * * DEBUG: section 15 Neighbor Routines * AUTHOR: Harvest Derived @@ -38,6 +38,7 @@ #include "ICP.h" #include "HttpRequest.h" #include "MemObject.h" +#include "ACLChecklist.h" /* count mcast group peers every 15 minutes */ #define MCAST_COUNT_RATE 900 @@ -124,7 +125,6 @@ peerAllowedToUse(const peer * p, request_t * request) { const struct _domain_ping *d = NULL; int do_ping = 1; - aclCheck_t checklist; assert(request != NULL); if (neighborType(p, request) == PEER_SIBLING) { if (request->flags.nocache) @@ -150,7 +150,7 @@ peerAllowedToUse(const peer * p, request_t * request) return do_ping; if (p->access == NULL) return do_ping; - memset(&checklist, '\0', sizeof(checklist)); + ACLChecklist checklist; checklist.src_addr = request->client_addr; checklist.my_addr = request->my_addr; checklist.my_port = request->my_port; diff --git a/src/protos.h b/src/protos.h index 071857c959..7054768958 100644 --- a/src/protos.h +++ b/src/protos.h @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.460 2003/01/23 00:37:24 robertc Exp $ + * $Id: protos.h,v 1.461 2003/01/28 01:29:35 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -52,13 +52,13 @@ SQUIDCEXTERN char *log_quote(const char *header); SQUIDCEXTERN int logTypeIsATcpHit(log_type); /* acl.c */ -SQUIDCEXTERN aclCheck_t *aclChecklistCreate(const struct _acl_access *, +SQUIDCEXTERN ACLChecklist *aclChecklistCreate(const struct _acl_access *, request_t *, const char *ident); -SQUIDCEXTERN void aclNBCheck(aclCheck_t *, PF *, void *); -SQUIDCEXTERN int aclCheckFast(const struct _acl_access *A, aclCheck_t *); -SQUIDCEXTERN void aclChecklistFree(aclCheck_t *); -SQUIDCEXTERN int aclMatchAclList(const acl_list * list, aclCheck_t * checklist); +SQUIDCEXTERN void aclNBCheck(ACLChecklist *, PF *, void *); +SQUIDCEXTERN int aclCheckFast(const struct _acl_access *A, ACLChecklist *); +SQUIDCEXTERN void aclChecklistFree(ACLChecklist *); +SQUIDCEXTERN int aclMatchAclList(const acl_list * list, ACLChecklist * checklist); SQUIDCEXTERN void aclDestroyAccessList(struct _acl_access **list); SQUIDCEXTERN void aclDestroyAcls(acl **); SQUIDCEXTERN void aclDestroyAclList(acl_list **); @@ -76,7 +76,7 @@ SQUIDCEXTERN const char *aclTypeToStr(squid_acl); SQUIDCEXTERN wordlist *aclDumpGeneric(const acl *); SQUIDCEXTERN int aclPurgeMethodInUse(acl_access *); SQUIDCEXTERN void aclCacheMatchFlush(dlink_list * cache); -SQUIDCEXTERN int aclAuthenticated(aclCheck_t * checklist); +SQUIDCEXTERN int aclAuthenticated(ACLChecklist * checklist); /* * cache_cf.c @@ -1081,10 +1081,10 @@ SQUIDCEXTERN void dump_externalAclHelper(StoreEntry * sentry, const char *name, SQUIDCEXTERN void free_externalAclHelper(external_acl **); SQUIDCEXTERN void aclParseExternal(void *curlist); SQUIDCEXTERN void aclDestroyExternal(void **curlust); -SQUIDCEXTERN int aclMatchExternal(void *dataptr, aclCheck_t * ch); +SQUIDCEXTERN int aclMatchExternal(void *dataptr, ACLChecklist * ch); SQUIDCEXTERN wordlist *aclDumpExternal(void *dataptr); typedef void EAH(void *data, void *result); -SQUIDCEXTERN void externalAclLookup(aclCheck_t * ch, void *acl_data, EAH * handler, void *data); +SQUIDCEXTERN void externalAclLookup(ACLChecklist * ch, void *acl_data, EAH * handler, void *data); SQUIDCEXTERN void externalAclInit(void); SQUIDCEXTERN void externalAclShutdown(void); SQUIDCEXTERN char *strtokFile(void); diff --git a/src/redirect.cc b/src/redirect.cc index cc8d1bcba5..3d65611865 100644 --- a/src/redirect.cc +++ b/src/redirect.cc @@ -1,6 +1,6 @@ /* - * $Id: redirect.cc,v 1.93 2003/01/23 00:37:25 robertc Exp $ + * $Id: redirect.cc,v 1.94 2003/01/28 01:29:35 robertc Exp $ * * DEBUG: section 61 Redirector * AUTHOR: Duane Wessels @@ -37,6 +37,7 @@ #include "authenticate.h" #include "Store.h" #include "client_side_request.h" +#include "ACLChecklist.h" typedef struct { void *data; @@ -106,8 +107,7 @@ redirectStart(clientHttpRequest * http, RH * handler, void *data) return; } if (Config.accessList.redirector) { - aclCheck_t ch; - memset(&ch, '\0', sizeof(ch)); + ACLChecklist ch; ch.src_addr = http->conn->peer.sin_addr; ch.my_addr = http->conn->me.sin_addr; ch.my_port = ntohs(http->conn->me.sin_port); diff --git a/src/snmp_core.cc b/src/snmp_core.cc index eadc8e04a9..5d8028a871 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -1,6 +1,6 @@ /* - * $Id: snmp_core.cc,v 1.60 2003/01/23 00:37:25 robertc Exp $ + * $Id: snmp_core.cc,v 1.61 2003/01/28 01:29:35 robertc Exp $ * * DEBUG: section 49 SNMP support * AUTHOR: Glenn Chisholm @@ -35,6 +35,7 @@ #include "squid.h" #include "comm.h" #include "cache_snmp.h" +#include "ACLChecklist.h" #define SNMP_REQUEST_SIZE 4096 #define MAX_PROTOSTAT 5 @@ -496,7 +497,6 @@ snmpDecodePacket(snmp_request_t * rq) { struct snmp_pdu *PDU; struct snmp_session Session; - aclCheck_t checklist; u_char *Community; u_char *buf = rq->buf; int len = rq->len; @@ -507,7 +507,7 @@ snmpDecodePacket(snmp_request_t * rq) PDU = snmp_pdu_create(0); Session.Version = SNMP_VERSION_1; Community = snmp_parse(&Session, PDU, buf, len); - memset(&checklist, '\0', sizeof(checklist)); + ACLChecklist checklist; checklist.src_addr = rq->from.sin_addr; checklist.snmp_community = (char *) Community; diff --git a/src/ssl.cc b/src/ssl.cc index da6da1c060..a536aa8481 100644 --- a/src/ssl.cc +++ b/src/ssl.cc @@ -1,6 +1,6 @@ /* - * $Id: ssl.cc,v 1.132 2003/01/23 00:37:25 robertc Exp $ + * $Id: ssl.cc,v 1.133 2003/01/28 01:29:35 robertc Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -38,6 +38,7 @@ #include "fde.h" #include "comm.h" #include "client_side_request.h" +#include "ACLChecklist.h" typedef struct { char *url; @@ -430,7 +431,6 @@ sslStart(clientHttpRequest * http, size_t * size_ptr, int *status_ptr) SslStateData *sslState = NULL; int sock; ErrorState *err = NULL; - aclCheck_t ch; int answer; int fd = http->conn->fd; request_t *request = http->request; @@ -444,7 +444,7 @@ sslStart(clientHttpRequest * http, size_t * size_ptr, int *status_ptr) /* * Check if this host is allowed to fetch MISSES from us (miss_access) */ - memset(&ch, '\0', sizeof(aclCheck_t)); + ACLChecklist ch; ch.src_addr = request->client_addr; ch.my_addr = request->my_addr; ch.my_port = request->my_port; diff --git a/src/structs.h b/src/structs.h index f2059324e4..71386da834 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.443 2003/01/27 08:08:51 hno Exp $ + * $Id: structs.h,v 1.444 2003/01/28 01:29:35 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -138,7 +138,7 @@ struct _snmp_request_t { int outlen; struct sockaddr_in from; struct snmp_pdu *PDU; - aclCheck_t *acl_checklist; + ACLChecklist *acl_checklist; u_char *community; }; @@ -177,27 +177,6 @@ struct _acl_tos { int tos; }; -struct _aclCheck_t { - const acl_access *accessList; - struct in_addr src_addr; - struct in_addr dst_addr; - struct in_addr my_addr; - unsigned short my_port; - request_t *request; - /* for acls that look at reply data */ - HttpReply *reply; - ConnStateData *conn; /* hack for ident and NTLM */ - char rfc931[USER_IDENT_SZ]; - auth_user_request_t *auth_user_request; - acl_lookup_state state[ACL_ENUM_MAX]; -#if SQUID_SNMP - char *snmp_community; -#endif - PF *callback; - void *callback_data; - external_acl_entry *extacl_entry; -}; - struct _wordlist { char *key; wordlist *next; @@ -1166,7 +1145,7 @@ struct _ps_state { peer *secho; #endif ping_data ping; - aclCheck_t *acl_checklist; + ACLChecklist *acl_checklist; }; #if USE_ICMP diff --git a/src/tunnel.cc b/src/tunnel.cc index 46961f1dd9..625e44d4cd 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1,6 +1,6 @@ /* - * $Id: tunnel.cc,v 1.132 2003/01/23 00:37:25 robertc Exp $ + * $Id: tunnel.cc,v 1.133 2003/01/28 01:29:35 robertc Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -38,6 +38,7 @@ #include "fde.h" #include "comm.h" #include "client_side_request.h" +#include "ACLChecklist.h" typedef struct { char *url; @@ -430,7 +431,6 @@ sslStart(clientHttpRequest * http, size_t * size_ptr, int *status_ptr) SslStateData *sslState = NULL; int sock; ErrorState *err = NULL; - aclCheck_t ch; int answer; int fd = http->conn->fd; request_t *request = http->request; @@ -444,7 +444,7 @@ sslStart(clientHttpRequest * http, size_t * size_ptr, int *status_ptr) /* * Check if this host is allowed to fetch MISSES from us (miss_access) */ - memset(&ch, '\0', sizeof(aclCheck_t)); + ACLChecklist ch; ch.src_addr = request->client_addr; ch.my_addr = request->my_addr; ch.my_port = request->my_port; diff --git a/src/typedefs.h b/src/typedefs.h index 1cb6b9093d..3c02951469 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.146 2003/01/23 00:37:27 robertc Exp $ + * $Id: typedefs.h,v 1.147 2003/01/28 01:29:35 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -75,7 +75,7 @@ typedef struct _acl_access acl_access; typedef struct _acl_address acl_address; typedef struct _acl_tos acl_tos; typedef struct _acl acl; -typedef struct _aclCheck_t aclCheck_t; +class ACLChecklist; typedef struct _wordlist wordlist; typedef struct _intlist intlist; typedef struct _intrange intrange;