Reloading acls (was: Re: Windows, yeeuch)

From: Andreas Lamprecht <andi@dont-contact.us>
Date: Mon, 8 Sep 1997 07:29:30 +0200 (MET DST)

Hello all!

I've included a patch which reloads acl-files when they have changed.
It is against squid-1.1.16 and my squids are running with this patch
for several days now (before that, it ran on 1.1.8 for several weeks ...)
I am reloading a large acl file with ~3000 entires 2-3 times a day.

But: Why not give squid a configure-interface like innd. squid would
wait on one end of a named pipe and then a simple program, maybe called
"ctlsquid" (from ctlinnd) could write simple commands like "reload acls"
to this pipe.

That's all!

And here's the patch:

diff -c squid-1.1.16/src/acl.c squid-1.1.16.1/src/acl.c
*** squid-1.1.16/src/acl.c Thu Apr 24 21:43:17 1997
--- squid-1.1.16.1/src/acl.c Mon Sep 1 09:25:46 1997
***************
*** 56,61 ****
--- 56,65 ----
  static int aclFromFile = 0;
  static FILE *aclFile;
  
+ /* These two to transport info from strtokFile to aclParseAclLine */
+ time_t aclfile_last_read_st_mtime = 0;
+ char *aclfile_last_read_filename = NULL;
+
  static void aclDestroyAclList _PARAMS((struct _acl_list * list));
  static void aclDestroyTimeList _PARAMS((struct _acl_time_data * data));
  static int aclMatchAclList _PARAMS((const struct _acl_list *, aclCheck_t *));
***************
*** 104,109 ****
--- 108,114 ----
  strtokFile(void)
  {
      char *t, *fn;
+ struct stat filestat;
      LOCAL_ARRAY(char, buf, 256);
  
    strtok_again:
***************
*** 120,130 ****
--- 125,142 ----
                  return (NULL);
              }
              aclFromFile = 1;
+ if(stat(fn, &filestat)) {
+ debug(28,0, "strtokFile: %s: cannot stat\n", fn);
+ } else {
+ aclfile_last_read_st_mtime = filestat.st_mtime;
+ aclfile_last_read_filename = xstrdup(fn);
+ }
          } else {
              return (t);
          }
      }
      /* aclFromFile */
+ read_again:
      if (fgets(buf, 256, aclFile) == NULL) {
          /* stop reading from file */
          fclose(aclFile);
***************
*** 135,140 ****
--- 147,157 ----
          /* skip leading and trailing white space */
          t += strspn(buf, w_space);
          t[strcspn(t, w_space)] = '\0';
+ if(*t == '#') /* Allow comments */
+ goto read_again;
+ if(strlen(t) == 0) /* Allow blank lines */
+ goto read_again;
+
          return (t);
      }
  }
***************
*** 654,659 ****
--- 671,685 ----
          debug_trap("Bad ACL type");
          break;
      }
+
+ if(aclfile_last_read_st_mtime) {
+ A->aclfile_st_mtime = aclfile_last_read_st_mtime;
+ aclfile_last_read_st_mtime = 0;
+ A->aclfile_filename = xstrdup(aclfile_last_read_filename);
+ safe_free(aclfile_last_read_filename);
+ A->aclfile_last_checked = squid_curtime;
+ }
+
      if (!new_acl)
          return;
      if (A->data == NULL) {
***************
*** 1047,1055 ****
--- 1073,1170 ----
      const request_t *r = checklist->request;
      const ipcache_addrs *ia = NULL;
      const char *fqdn = NULL;
+ char *my_cfgline;
      int k;
+ struct stat filestat;
+
      if (!acl)
          return 0;
+
+ if(acl->aclfile_last_checked && (squid_curtime - acl->aclfile_last_checked) > Config.aclfile_CheckInterval) {
+ debug(28,2, "aclMatchAcl: checking if aclfile \"%s\" has changed\n", acl->aclfile_filename);
+ if(stat(acl->aclfile_filename, &filestat)) {
+ debug(28,0, "aclMatchAcl: cannot stat \"%s\"\n", acl->aclfile_filename);
+ } else {
+ if(filestat.st_mtime > acl->aclfile_st_mtime) {
+ debug(28,1, "aclMatchAcl: re-reading aclfile \"%s\"\n", acl->aclfile_filename);
+
+ /* Reinitialize strtok */
+ my_cfgline = xstrdup(acl->cfgline);
+ strtok(my_cfgline, w_space); /* acl */
+ strtok(NULL, w_space); /* name */
+ strtok(NULL, w_space); /* type */
+
+ /* Delete old acl->data and re-read it */
+ switch (acl->type) {
+ case ACL_SRC_IP:
+ case ACL_DST_IP:
+ #if defined (USE_SPLAY_TREE)
+ splay_destroy(acl->data, xfree);
+ #elif defined(USE_BIN_TREE)
+ aclDestroyTree(acl->data);
+ #else /* LINKED LIST */
+ aclDestroyIpList(acl->data);
+ #endif
+ acl->data = NULL;
+ aclParseIpList(&acl->data);
+ break;
+ case ACL_DST_DOMAIN:
+ case ACL_SRC_DOMAIN:
+ #if defined(USE_SPLAY_TREE)
+ splay_destroy(acl->data, xfree);
+ #elif defined(USE_BIN_TREE)
+ aclDestroyTree(acl->data);
+ #else /* LINKED LIST */
+ wordlistDestroy((wordlist **) & acl->data);
+ #endif
+ acl->data = NULL;
+ aclParseDomainList(&acl->data);
+ break;
+ case ACL_USER:
+ wordlistDestroy((wordlist **) & acl->data);
+ Config.identLookup = 1;
+ acl->data = NULL;
+ aclParseWordList(&acl->data);
+ break;
+ case ACL_TIME:
+ aclDestroyTimeList(acl->data);
+ acl->data = NULL;
+ aclParseTimeSpec(&acl->data);
+ break;
+ case ACL_URL_REGEX:
+ case ACL_URLPATH_REGEX:
+ case ACL_BROWSER:
+ aclDestroyRegexList(acl->data);
+ acl->data = NULL;
+ aclParseRegexList(&acl->data, 0);
+ break;
+ case ACL_URL_PORT:
+ intlistDestroy((intlist **) & acl->data);
+ acl->data = NULL;
+ aclParseIntlist(&acl->data);
+ break;
+ case ACL_PROTO:
+ intlistDestroy((intlist **) & acl->data);
+ acl->data = NULL;
+ aclParseProtoList(&acl->data);
+ case ACL_METHOD:
+ intlistDestroy((intlist **) & acl->data);
+ acl->data = NULL;
+ aclParseMethodList(&acl->data);
+ break;
+ case ACL_NONE:
+ default:
+ fatal_dump("aclDestroyAcls: Found ACL_NONE?");
+ break;
+ }
+ xfree(my_cfgline);
+
+ acl->aclfile_st_mtime = filestat.st_mtime;
+ }
+ acl->aclfile_last_checked = squid_curtime;
+ }
+ }
+
      debug(28, 3, "aclMatchAcl: checking '%s'\n", acl->cfgline);
      switch (acl->type) {
      case ACL_SRC_IP:
diff -c squid-1.1.16/src/acl.h squid-1.1.16.1/src/acl.h
*** squid-1.1.16/src/acl.h Thu Feb 20 22:03:10 1997
--- squid-1.1.16.1/src/acl.h Mon Sep 1 10:02:07 1997
***************
*** 96,101 ****
--- 96,104 ----
      squid_acl type;
      void *data;
      char *cfgline;
+ char *aclfile_filename;
+ time_t aclfile_last_checked;
+ time_t aclfile_st_mtime;
      struct _acl *next;
  };
  
diff -c squid-1.1.16/src/cache_cf.c squid-1.1.16.1/src/cache_cf.c
*** squid-1.1.16/src/cache_cf.c Thu Aug 21 21:17:04 1997
--- squid-1.1.16.1/src/cache_cf.c Mon Sep 1 09:31:03 1997
***************
*** 209,215 ****
--- 209,217 ----
  #define DefaultOptionsClientDb 1 /* default on */
  #define DefaultOptionsQueryIcmp 0 /* default off */
  
+ #define DefaultAclFileCheckInterval 300
  
+
  int httpd_accel_mode = 0; /* for fast access */
  const char *DefaultSwapDir = DEFAULT_SWAP_DIR;
  const char *DefaultConfigFile = DEFAULT_CONFIG_FILE;
***************
*** 1143,1148 ****
--- 1145,1153 ----
          else if (!strcmp(token, "acl"))
              aclParseAclLine();
  
+ else if (!strcmp(token, "aclfile_checkinterval"))
+ parseIntegerValue(&Config.aclfile_CheckInterval);
+
          else if (!strcmp(token, "deny_info"))
              aclParseDenyInfoLine(&DenyInfoList);
  
***************
*** 1611,1616 ****
--- 1620,1626 ----
      Config.Options.anonymizer = DefaultOptionsAnonymizer;
      Config.Options.icp_hit_stale = DefaultOptionsIcpHitStale;
      Config.Options.enable_purge = DefaultOptionsEnablePurge;
+ Config.aclfile_CheckInterval = DefaultAclFileCheckInterval;
      Config.Options.client_db = DefaultOptionsClientDb;
      Config.Options.query_icmp = DefaultOptionsQueryIcmp;
  #ifdef RELOAD_INTO_IMS
diff -c squid-1.1.16/src/cache_cf.h squid-1.1.16.1/src/cache_cf.h
*** squid-1.1.16/src/cache_cf.h Thu Aug 7 22:49:23 1997
--- squid-1.1.16.1/src/cache_cf.h Mon Sep 1 09:33:23 1997
***************
*** 282,287 ****
--- 283,289 ----
          int reload_into_ims;
  #endif /* RELOAD_INTO_IMS */
      } Options;
+ int aclfile_CheckInterval;
      char *fake_ua;
  };
  
diff -c squid-1.1.16/src/squid.conf.pre.in squid-1.1.16.1/src/squid.conf.pre.in
*** squid-1.1.16/src/squid.conf.pre.in Thu Aug 7 22:38:02 1997
--- squid-1.1.16.1/src/squid.conf.pre.in Mon Sep 1 09:39:43 1997
***************
*** 1166,1171 ****
--- 1166,1180 ----
  #
  #http_anonymizer off
  
+ # TAG: aclfile_checkinterval
+ # If you are using config files for your acls, these files
+ # are checked for changes after this interval.
+ # If the modification time has changed, they are reloaded.
+ #
+ # default are 300 seconds
+ #aclfile_checkinterval 300
+
+
  # TAG: fake_user_agent
  # If you use the paranoid http_anonymizer setting, Squid will strip
  # your User-agent string from the request. Some Web servers will
Received on Tue Jul 29 2003 - 13:15:43 MDT

This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:11:25 MST