In article <199609252025.WAA10200@adv.IAEhv.nl> I wrote:
>I've made a patch to read src and dst ACL's from a file (one entry per
>line), the new commands are 'acl <name> src_file <file>' and 'acl <name>
>dst_file <file>'.
>
>Furthermore I added a small patch to implement the ACL lookup speedup
>described above: a matched record in an ACL will be moved to the second
>position of the list (the first position is somewhat more difficult). This
[...]
I've made the patch more general. You can now use for any ACL the
following syntax:
acl <aclname> <acltype> "file"
A file should contain one word (IP spec, domain name, regexp, etc.) per
line. Note that you can mix this new file method with the old method, e.g.:
acl acl1 src 212.1.2.3/24 "/home/squid/etc/networks" 127.0.0.1
Furthermore the ACL speedup patch has been implemented for domain lists,
regex lists and int lists too.
The patch was made for 1.1beta4.
Arjan
-----------------------------------------------------------------------------
--- acl.c.orig Fri Sep 20 08:28:24 1996
+++ acl.c Sat Sep 28 23:11:31 1996
@@ -33,6 +33,10 @@
/* Global */
char *AclMatchedName = NULL;
+/* for reading ACL's from files */
+int aclFromFile = 0;
+FILE *aclFile;
+
/* These three should never be referenced directly in this file! */
struct _acl_deny_info_list *DenyInfoList = NULL;
struct _acl_access *HTTPAccessList = NULL;
@@ -65,6 +69,44 @@
static squid_acl aclType _PARAMS((char *s));
static int decode_addr _PARAMS((char *, struct in_addr *, struct in_addr *));
+char *
+strtokFile(void)
+{
+ char *t, *fn;
+ LOCAL_ARRAY(char, buf, 256);
+
+strtok_again:
+ if (!aclFromFile) {
+ t = (strtok(NULL, w_space));
+ if (t && (*t == '\"' || *t == '\'')) {
+ /* quote found, start reading from file */
+ fn = ++t;
+ while (*t && *t != '\"' && *t != '\'') t++;
+ *t = '\0';
+ if ((aclFile = fopen(fn, "r")) == NULL) {
+ debug(28, 0, "strtokFile: %s not found\n", fn);
+ return(NULL);
+ }
+ aclFromFile = 1;
+ } else {
+ return(t);
+ }
+ }
+ /* aclFromFile */
+ if (fgets(buf, 256, aclFile) == NULL) {
+ /* stop reading from file */
+ fclose(aclFile);
+ aclFromFile = 0;
+ goto strtok_again;
+ } else {
+ t = buf;
+ /* skip leading and trailing white space */
+ t += strspn(buf, w_space);
+ t[strcspn(t, w_space)] = '\0';
+ return(t);
+ }
+}
+
static squid_acl
aclType(char *s)
{
@@ -115,7 +157,7 @@
intlist **Tail = &head;
intlist *q = NULL;
char *t = NULL;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
q = xcalloc(1, sizeof(intlist));
q->i = atoi(t);
*(Tail) = q;
@@ -131,7 +173,7 @@
intlist **Tail = &head;
intlist *q = NULL;
char *t = NULL;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
q = xcalloc(1, sizeof(intlist));
q->i = (int) urlParseProtocol(t);
*(Tail) = q;
@@ -147,7 +189,7 @@
intlist **Tail = &head;
intlist *q = NULL;
char *t = NULL;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
q = xcalloc(1, sizeof(intlist));
q->i = (int) urlParseMethod(t);
*(Tail) = q;
@@ -223,7 +265,7 @@
LOCAL_ARRAY(char, addr2, 256);
LOCAL_ARRAY(char, mask, 256);
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
q = xcalloc(1, sizeof(struct _acl_ip_data));
if (!strcasecmp(t, "all")) {
q->addr1.s_addr = 0;
@@ -286,7 +328,7 @@
char *t = NULL;
data = xcalloc(1, sizeof(struct _acl_time_data));
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
if (*t < '0' || *t > '9') {
/* assume its day-of-week spec */
while (*t) {
@@ -360,7 +402,7 @@
relist *q = NULL;
char *t = NULL;
regex_t comp;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
if (regcomp(&comp, t, REG_EXTENDED) != REG_NOERROR) {
debug(28, 0, "%s line %d: %s\n",
cfg_filename, config_lineno, config_input_line);
@@ -383,7 +425,7 @@
wordlist **Tail = &head;
wordlist *q = NULL;
char *t = NULL;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
q = xcalloc(1, sizeof(wordlist));
q->key = xstrdup(t);
*(Tail) = q;
@@ -399,7 +441,7 @@
wordlist **Tail = &head;
wordlist *q = NULL;
char *t = NULL;
- while ((t = strtok(NULL, w_space))) {
+ while ((t = strtokFile())) {
Tolower(t);
q = xcalloc(1, sizeof(wordlist));
q->key = xstrdup(t);
@@ -630,7 +672,10 @@
{
struct in_addr h;
unsigned long lh, la1, la2;
+ struct _acl_ip_data *first, *prev;
+ first = data; /* remember first element, this will never be moved */
+ prev = NULL; /* previous element in the list */
while (data) {
h.s_addr = c.s_addr & data->mask.s_addr;
debug(28, 3, "aclMatchIp: h = %s\n", inet_ntoa(h));
@@ -639,6 +684,13 @@
if (!data->addr2.s_addr) {
if (h.s_addr == data->addr1.s_addr) {
debug(28, 3, "aclMatchIp: returning 1\n");
+ if (prev != NULL) {
+ /* shift the element just found to the second position
+ in the list */
+ prev->next = data->next;
+ data->next = first->next;
+ first->next = data;
+ }
return 1;
}
} else {
@@ -651,6 +703,7 @@
return 1;
}
}
+ prev = data;
data = data->next;
}
debug(28, 3, "aclMatchIp: returning 0\n");
@@ -660,27 +713,52 @@
static int
aclMatchDomainList(wordlist * data, char *host)
{
+ wordlist *first, *prev;
+
if (host == NULL)
return 0;
debug(28, 3, "aclMatchDomainList: checking '%s'\n", host);
+ first = data;
+ prev = NULL;
for (; data; data = data->next) {
debug(28, 3, "aclMatchDomainList: looking for '%s'\n", data->key);
- if (matchDomainName(data->key, host))
+ if (matchDomainName(data->key, host)) {
+ if (prev != NULL) {
+ /* shift the element just found to the second position
+ in the list */
+ prev->next = data->next;
+ data->next = first->next;
+ first->next = data;
+ }
return 1;
}
+ prev = data;
+ }
return 0;
}
static int
aclMatchRegex(relist * data, char *word)
{
+ relist *first, *prev;
if (word == NULL)
return 0;
debug(28, 3, "aclMatchRegex: checking '%s'\n", word);
+ first = data;
+ prev = NULL;
while (data) {
debug(28, 3, "aclMatchRegex: looking for '%s'\n", data->pattern);
- if (regexec(&data->regex, word, 0, 0, 0) == 0)
+ if (regexec(&data->regex, word, 0, 0, 0) == 0) {
+ if (prev != NULL) {
+ /* shift the element just found to the second position
+ in the list */
+ prev->next = data->next;
+ data->next = first->next;
+ first->next = data;
+ }
return 1;
+ }
+ prev = data;
data = data->next;
}
return 0;
@@ -689,9 +767,21 @@
static int
aclMatchInteger(intlist * data, int i)
{
+ intlist *first, *prev;
+ first = data;
+ prev = NULL;
while (data) {
- if (data->i == i)
+ if (data->i == i) {
+ if (prev != NULL) {
+ /* shift the element just found to the second position
+ in the list */
+ prev->next = data->next;
+ data->next = first->next;
+ first->next = data;
+ }
return 1;
+ }
+ prev = data;
data = data->next;
}
return 0;
--- squid.conf.pre.in.orig Thu Sep 26 21:19:21 1996
+++ squid.conf.pre.in Sat Sep 28 22:15:47 1996
@@ -637,12 +637,15 @@
# Defining an Access List
#
# acl aclname acltype string1 ...
+# acl aclname acltype "file" ...
#
-# acltype is one of src dst srcdomain dstdomain url_pattern urlpath_pattern
+# when using "file", the file should contain one item per line
+#
+# acltype is one of src dst srcdomain dstdomain url_regex urlpath_regex
# time port proto method
#
# acl aclname src ip-address/netmask ... (clients IP address)
-# acl aclname src addr1/mask1-addr2/mask2 ... (range of addresses)
+# acl aclname src addr1-addr2/mask2 ... (range of addresses)
# acl aclname dst ip-address/netmask ... (URL host's IP address)
# acl aclname srcdomain foo.com ... (taken from reverse DNS lookup)
# acl aclname dstdomain foo.com ... (taken from the URL)
Received on Sat Sep 28 1996 - 15:15:08 MDT
This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:33:05 MST