diff -c -r ../../cached-1.4.pl2/src/configure.in ./configure.in
*** ../../cached-1.4.pl2/src/configure.in	Tue Dec 19 03:33:32 1995
--- ./configure.in	Sat Jan 20 23:29:23 1996
***************
*** 102,108 ****
  AC_HEADER_STDC
  AC_CHECK_HEADERS(config.h fcntl.h memory.h stdlib.h string.h unistd.h \
                   syslog.h sys/file.h sys/types.h sys/syslog.h sys/time.h \
!                  regex.h netinet/in.h arpa/inet.h crypt.h alloca.h)
  AC_EGREP_HEADER(mxfast, malloc.h, [XTRA_CFLAGS="$XTRA_CFLAGS -DLNG_MALLINFO"], [XTRA_CFLAGS="$XTRA_CFLAGS"])
  
  dnl Check for typedefs
--- 102,109 ----
  AC_HEADER_STDC
  AC_CHECK_HEADERS(config.h fcntl.h memory.h stdlib.h string.h unistd.h \
                   syslog.h sys/file.h sys/types.h sys/syslog.h sys/time.h \
!                  regex.h netinet/in.h arpa/inet.h crypt.h alloca.h \
!                  ndbm.h)
  AC_EGREP_HEADER(mxfast, malloc.h, [XTRA_CFLAGS="$XTRA_CFLAGS -DLNG_MALLINFO"], [XTRA_CFLAGS="$XTRA_CFLAGS"])
  
  dnl Check for typedefs
***************
*** 133,138 ****
--- 134,142 ----
  AC_CHECK_LIB(nsl, main, [XTRA_LIBS="$XTRA_LIBS -lnsl"])
  AC_CHECK_LIB(resolv, main, [XTRA_LIBS="$XTRA_LIBS -lresolv"])
  AC_CHECK_LIB(bsd, main, [XTRA_LIBS="$XTRA_LIBS -lbsd"])
+ 
+ dnl Check for ndbm library
+ AC_CHECK_LIB(dbm, dbm_open, [XTRA_LIBS="$XTRA_LIBS -ldbm"])
  
  dnl We found a version of libresolv on SunOS 4.x which requires -l44bsd
  dnl We have to first check to see if -l44bsd is present and has the
diff -c -r ../../cached-1.4.pl2/src/server/cache_cf.c ./server/cache_cf.c
*** ../../cached-1.4.pl2/src/server/cache_cf.c	Tue Jan 16 02:44:53 1996
--- ./server/cache_cf.c	Sat Jan 20 23:29:29 1996
***************
*** 140,145 ****
--- 140,148 ----
  	char *hierarchy;
  	int rotateNumber;
      } Log;
+ #if defined(HAVE_NDBM_H)
+     char *asDatabase;
+ #endif
      char *adminEmail;
      char *effectiveUser;
      char *effectiveGroup;
***************
*** 201,206 ****
--- 204,212 ----
  #define DefaultHierarchyLogFile "cache.hierarchy.log"
  #define DefaultLogRotateNumber  10
  #define DefaultAdminEmail	"webmaster"
+ #if defined(HAVE_NDBM_H)
+ #define DefaultASDatabase	"/etc/net2as"
+ #endif
  #define DefaultFtpgetProgram	"ftpget"
  #define DefaultDnsserverProgram "dnsserver"
  #define DefaultEffectiveUser	(char *)NULL	/* default NONE */
***************
*** 685,690 ****
--- 691,709 ----
  
  }
  
+ #if defined(HAVE_NDBM_H)
+ void parseAsDatabaseLine(line_in)
+      char *line_in;
+ {
+     char *token;
+     token = strtok(NULL, w_space);
+     if (token == (char *) NULL)
+         self_destruct(line_in);
+     safe_free(Config.asDatabase);
+     Config.asDatabase = xstrdup(token);
+ }
+ #endif
+ 
  void parseHttpdAccelLine(line_in)
       char *line_in;
  {
***************
*** 1100,1105 ****
--- 1119,1130 ----
  	else if (!strcmp(token, "cache_dir"))
  	    parseDirLine(line_in);
  
+ #if defined(HAVE_NDBM_H)
+ 	/* Parse an as_database line */
+ 	else if (!strcmp(token, "autonomous_systems_database"))
+ 	    parseAsDatabaseLine(line_in);
+ #endif
+ 
  	/* Parse a cache_log line */
  	else if (!strcmp(token, "cache_log"))
  	    parseLogLine(line_in);
***************
*** 1613,1618 ****
--- 1638,1649 ----
  {
      return Config.adminEmail;
  }
+ #if defined(HAVE_NDBM_H)
+ char *getASDatabase()
+ {
+     return Config.asDatabase;
+ }
+ #endif
  int getDebugLevel()
  {
      return Config.debugLevel;
***************
*** 1688,1693 ****
--- 1719,1727 ----
      Config.neighborTimeout = DefaultNeighborTimeout;
      Config.singleParentBypass = DefaultSingleParentBypass;
      Config.adminEmail = safe_xstrdup(DefaultAdminEmail);
+ #if defined(HAVE_NDBM_H)
+     Config.asDatabase = safe_xstrdup(DefaultASDatabase);
+ #endif
      Config.effectiveUser = safe_xstrdup(DefaultEffectiveUser);
      Config.effectiveGroup = safe_xstrdup(DefaultEffectiveGroup);
      Config.appendDomain = safe_xstrdup(DefaultAppendDomain);
diff -c -r ../../cached-1.4.pl2/src/server/cached.conf ./server/cached.conf
*** ../../cached-1.4.pl2/src/server/cached.conf	Tue Jan 16 02:44:55 1996
--- ./server/cached.conf	Sun Jan 21 20:39:00 1996
***************
*** 129,134 ****
--- 129,150 ----
  #		* Cache hosts with no domain restrictions are queried
  #		  for all requests.
  #		* There are no defaults.
+ #
+ # 	Autonomous Systems extension for cache_host_domain (need NDBM to
+ # 	be used) :
+ # 	You can specify Autonomous Systems instead of domains with
+ # 	cache_host_domain if you have built a net2as database.
+ # 	For example, specifying
+ #
+ #		cache_host_domain bigserver.enst.fr !AS1717
+ #
+ #	has the effect such that query packets are sent to
+ #	'bigserver' only when the requested object exists on a
+ #	server in the Autonomous System AS1717.
+ 
+ #  TAG: autonomous_systems_database
+ #	Autonomous Systems index file. The default is /etc/net2as.
+ #autonomous_systems_database /etc/net2as
  
  #
  #  TAG:	inside_firewall
diff -c -r ../../cached-1.4.pl2/src/server/neighbors.c ./server/neighbors.c
*** ../../cached-1.4.pl2/src/server/neighbors.c	Thu Jan 18 21:05:44 1996
--- ./server/neighbors.c	Sun Jan 21 17:46:43 1996
***************
*** 91,96 ****
--- 91,100 ----
  #include <netdb.h>
  #include <fcntl.h>
  
+ #if defined(HAVE_NDBM_H)
+ #include <ndbm.h>
+ #endif
+ 
  #include "ansihelp.h"
  #include "comm.h"
  #include "store.h"
***************
*** 223,228 ****
--- 227,287 ----
  	fflush(cache_hierarchy_log);
  }
  
+ #if defined(HAVE_NDBM_H)
+ 
+ #  if !defined(MIN)
+ #  define MIN(a, b) ((a < b) ? (a) : (b))
+ #  endif
+ 
+ static char *net2as(net)
+      u_long net;
+ {
+     static int firstCall = 0;
+     static DBM *db;
+     static char key[] = "xxx.xxx.xxx.xxx/xx";
+     static char as [] = "xxxxx";
+     u_long addr;
+     static datum key_dat, content_dat;
+     int i;
+ 
+     if (!firstCall) {
+       firstCall++;
+       db = dbm_open(getASDatabase(), O_RDONLY, 0);
+       if (!db) {
+ 	debug(0, "net2as: %s: %s\n", getASDatabase(), xstrerror());
+ 	_exit(1);
+       }
+       key_dat.dptr = key;
+     }
+ 
+ /*
+  * ALWAYS start with length 24 to work correctly even if we encounter
+  * RFC 1797 Experiment networks : For class A and B addresses, we
+  * don't start searching announces of length 8 or 16 because some
+  * folks on the INTERNET are announcing subnets of class A (and
+  * perhaps some day class B) networks with BGP4.  This means that it
+  * may be possible to have several subnets of a class A or B network
+  * announced by different autonomous systems...
+  */
+     for (i = 24; i; i--) {
+       addr = net & ~((1L<<(32-i))-1);
+       sprintf(key, "%lu.%lu.%lu.%lu/%d", addr>>24, (addr>>16) & 0xff,
+ 	      (addr>>8) & 0xff, addr & 0xff, i);
+       if (i == 24) debug(5, "net2as: checking AS for %s\n", key);
+       key_dat.dsize = strlen(key);
+       content_dat = dbm_fetch(db, key_dat);
+       if (content_dat.dptr) {
+ 	strncpy(as, content_dat.dptr, MIN(content_dat.dsize, sizeof(as) - 1));
+ 	as[MIN(content_dat.dsize, sizeof(as) - 1)] = 0;
+ 	debug(5, "net2as: AS(%s) = AS%s\n", key, as);
+ 	return as;
+       }
+     }
+     debug(5, "net2as: no AS found for this network\n");
+     return NULL;
+ }
+ #endif
+ 
  static int edgeWouldBePinged(e, host)
       edge *e;
       char *host;
***************
*** 231,241 ****
--- 290,328 ----
      dom_list *d = NULL;
      int do_ping = 1;
  
+ #if defined(HAVE_NDBM_H)
+     struct hostent *hep = NULL;
+     u_long address = 0;
+     char *as;
+ #endif
+ 
      if (e->domains == NULL)
  	return do_ping;
  
      do_ping = 0;
      for (d = e->domains; d; d = d->next) {
+ #if defined(HAVE_NDBM_H)
+       if (!strncasecmp(d->domain, "as", 2) && !strchr(d->domain, '.')) {
+ 	switch (address) {
+ 	case -1L:
+ 	  do_ping = !d->do_ping;
+ 	  continue;
+ 	case 0:
+ 	  if (host && (hep = ipcache_gethostbyname(host)) &&
+ 	      (hep->h_length >= 4)) address = ntohl(*(u_long *) hep->h_addr);
+ 	  else {
+ 	    address = -1L;
+ 	    do_ping = !d->do_ping;
+ 	    continue;
+ 	  }
+ 	default:
+ 	  as = net2as(address);
+ 	  /* if found a match, no need to check any more domains */
+ 	  if (as && !strcasecmp(as, d->domain + 2)) return d->do_ping;
+ 	  else do_ping = !d->do_ping;
+ 	}
+       } else {
+ #endif
  	if ((offset = strlen(host) - strlen(d->domain)) < 0) {
  	    do_ping = !d->do_ping;
  	    continue;
***************
*** 246,252 ****
  	    break;
  	} else {
  	    do_ping = !d->do_ping;
! 	}
      }
      return do_ping;
  }
--- 333,342 ----
  	    break;
  	} else {
  	    do_ping = !d->do_ping;
!         }
! #if defined(HAVE_NDBM_H)
!       }
! #endif
      }
      return do_ping;
  }
