bind-dbm - dead code, submitted for anyone else's possible use

Paul A Vixie vixie at mibh.net
Fri Aug 6 06:16:24 UTC 1999


someone named "kc" (hence these filenames) asked me for a histogram of
f.root-servers.net's client addresses for something called "skitter".
lacking, as i usually do, both time and ambition and cleverness, i did
a simple "ndbm" hack to get this done.  enclosed below are:

	kcdiffs - which apply against 8.2.1 and run fine on digital unix
	kcdump.c - which can convert the .dir/.pag files to printable ascii
	kcanal.pl - which effectively "cat"'s multiple kcdump outputs

ndbm is funky from a performance point of view.  it starts out doing
about 1000 transactions per second and then once the .pag file gets over
about 1MB it goes down to about 300 transactions per second.  since my
root name servers each do 1500 to 2000 queries per second, you can bet
that i didn't run this for very long before deciding that the sleepycat
"BerkeleyDB" package would have been a better choice.  maybe next time.

i hate killing working code, so here it is in case anybody wants it.

(btw, the "plock" stuff is only for digital unix, rip it out elsewise.)

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1999-08-05 23:09 PDT by <vixie at bb.rc.vix.com>.
# Source directory was `/tmp_mnt/mb/mb0/user/vixie'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#   3331 -rw-rw-r-- kcdiffs
#    777 -rw-rw-r-- kcdump.c
#    136 -rwxrwxr-x kcanal.pl
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh25359; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= kcdiffs ==============
if test -f 'kcdiffs' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'kcdiffs' '(file already exists)'
else
  $echo 'x -' extracting 'kcdiffs' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'kcdiffs' &&
Index: named/db_func.h
===================================================================
RCS file: /proj/cvs/isc/bind/src/bin/named/db_func.h,v
retrieving revision 8.35
diff -c -r8.35 db_func.h
*** named/db_func.h	1999/03/16 02:21:26	8.35
--- named/db_func.h	1999/07/29 22:05:31
***************
*** 177,182 ****
--- 177,185 ----
X  extern time_t		db_lame_find(char *zone, struct databuf *dp);
X  extern void 		db_lame_clean(void);
X  extern void 		db_lame_destroy(void);
+ extern void		client_histogram_open(char *basename);
+ extern void		client_histogram_close(void);
+ extern void		client_histogram_write(const struct in_addr *inap);
X  /* --from db_glue.c-- */
X  
X  /* ++from db_lookup.c++ */
Index: named/db_glue.c
===================================================================
RCS file: /proj/cvs/isc/bind/src/bin/named/db_glue.c,v
retrieving revision 8.36
diff -c -r8.36 db_glue.c
*** named/db_glue.c	1999/05/11 23:48:39	8.36
--- named/db_glue.c	1999/07/29 22:32:18
***************
*** 762,764 ****
--- 762,800 ----
X  	lame_hash_size = 0;
X  	lame_hash = NULL;
X  }
+ 
+ #include <fcntl.h>
+ #include <ndbm.h>
+ 
+ DBM *client_histogram = NULL;
+ 
+ void
+ client_histogram_open(char *basename) {
+ 	client_histogram = dbm_open(basename, O_RDWR|O_CREAT, 0664);
+ }
+ 
+ void
+ client_histogram_close(void) {
+ 	if (client_histogram != NULL) {
+ 		dbm_close(client_histogram);
+ 		client_histogram = NULL;
+ 	}
+ }
+ 
+ void
+ client_histogram_write(const struct in_addr *inap) {
+ 	unsigned long ul;
+ 	datum key, val;
+ 
+ 	key.dptr = (char *)inap;
+ 	key.dsize = sizeof *inap;
+ 	val = dbm_fetch(client_histogram, key);
+ 	if (val.dptr != NULL && val.dsize == sizeof ul)
+ 		memcpy(&ul, val.dptr, val.dsize);
+ 	else
+ 		ul = 0;
+ 	ul++;
+ 	val.dptr = (char *)&ul;
+ 	val.dsize = sizeof ul;
+ 	dbm_store(client_histogram, key, val, DBM_REPLACE);
+ }
Index: named/ns_main.c
===================================================================
RCS file: /proj/cvs/isc/bind/src/bin/named/ns_main.c,v
retrieving revision 8.101
diff -c -r8.101 ns_main.c
*** named/ns_main.c	1999/06/18 02:26:54	8.101
--- named/ns_main.c	1999/07/29 22:10:54
***************
*** 101,106 ****
--- 101,107 ----
X  #else
X  # include <sys/mbuf.h>
X  #endif
+ #include <sys/lock.h>
X  
X  #include <netinet/in.h>
X  #include <net/route.h>
***************
*** 506,511 ****
--- 507,514 ----
X  	ns_notice(ns_log_default, "Ready to answer queries.");
X  	gettime(&tt);
X  	prime_cache();
+ 	plock(PROCLOCK);
+ 	client_histogram_open("/var/tmp/named_clients");
X  	while (!main_needs_exit) {
X  		evEvent event;
X  
***************
*** 522,527 ****
--- 525,531 ----
X  		}
X  	}
X  	ns_info(ns_log_default, "named shutting down");
+ 	client_histogram_close();
X  #ifdef BIND_UPDATE
X  	dynamic_about_to_exit();
X  #endif
***************
*** 700,705 ****
--- 704,710 ----
X  		return;
X  	}
X  	sp->s_rfd = rfd;	/* stream file descriptor */
+ 	client_histogram_write(&ra->sin_addr);
X  	gettime(&tt);
X  	sp->s_time = tt.tv_sec;	/* last transaction time */
X  	sp->s_from = *ra;	/* address to respond to */
***************
*** 991,996 ****
--- 996,1002 ----
X  		ns_debug(ns_log_default, 1, "truncated oversize UDP packet");
X  	}
X  
+ 	client_histogram_write(&from.sin_addr);
X  	dispatch_message(u.buf, n, PACKETSZ, NULL, from, fd, ifp);
X  	if (++nudp < nudptrans)
X  		goto more;
SHAR_EOF
  $shar_touch -am 0805230999 'kcdiffs' &&
  chmod 0664 'kcdiffs' ||
  $echo 'restore of' 'kcdiffs' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'kcdiffs:' 'MD5 check failed'
d250ee1fafb4978d76cbcbd67f16f131  kcdiffs
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'kcdiffs'`"
    test 3331 -eq "$shar_count" ||
    $echo 'kcdiffs:' 'original size' '3331,' 'current size' "$shar_count!"
  fi
fi
# ============= kcdump.c ==============
if test -f 'kcdump.c' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'kcdump.c' '(file already exists)'
else
  $echo 'x -' extracting 'kcdump.c' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'kcdump.c' &&
#include <sys/types.h>
#include <sys/fcntl.h>
X
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
X
#include <stdio.h>
#include <ndbm.h>
#include <stdlib.h>
#include <unistd.h>
X
main(int argc, char **argv) {
X	const char basename[] = "/var/tmp/named_clients";
X	struct in_addr ina;
X	unsigned long ul;
X	datum key, val;
X	DBM *db;
X
X	db = dbm_open(basename, O_RDONLY, 0);
X	if (!db) {
X		perror(basename);
X		exit(1);
X	}
X	for (key = dbm_firstkey(db); key.dptr != NULL; key = dbm_nextkey(db)) {
X		if (key.dsize != sizeof ina)
X			continue;
X		memcpy(&ina, key.dptr, key.dsize);
X		val = dbm_fetch(db, key);
X		if (val.dptr != NULL && val.dsize == sizeof ul)
X			memcpy(&ul, val.dptr, val.dsize);
X		else
X			ul = 0;
X		printf("%s %lu\n", inet_ntoa(ina), ul);
X	}
X	exit(0);
}
SHAR_EOF
  $shar_touch -am 0729153899 'kcdump.c' &&
  chmod 0664 'kcdump.c' ||
  $echo 'restore of' 'kcdump.c' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'kcdump.c:' 'MD5 check failed'
4ca56d6e8ad135916ad70ccf1c66cd8c  kcdump.c
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'kcdump.c'`"
    test 777 -eq "$shar_count" ||
    $echo 'kcdump.c:' 'original size' '777,' 'current size' "$shar_count!"
  fi
fi
# ============= kcanal.pl ==============
if test -f 'kcanal.pl' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'kcanal.pl' '(file already exists)'
else
  $echo 'x -' extracting 'kcanal.pl' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'kcanal.pl' &&
#!/usr/bin/perl
X
while (<>) {
X	chop; split;
X	$r{$_[0]} += $_[1];
}
X
while (($key, $val) = each %r) {
X	print "$val\t$key\n";
}
X
exit(0);
SHAR_EOF
  $shar_touch -am 0729164599 'kcanal.pl' &&
  chmod 0775 'kcanal.pl' ||
  $echo 'restore of' 'kcanal.pl' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'kcanal.pl:' 'MD5 check failed'
fd07e5a746aa8ad5e1b8260e6267d11f  kcanal.pl
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'kcanal.pl'`"
    test 136 -eq "$shar_count" ||
    $echo 'kcanal.pl:' 'original size' '136,' 'current size' "$shar_count!"
  fi
fi
rm -fr _sh25359
exit 0


More information about the bind-workers mailing list