diff srvrlib/db.h @ 0:c7f6b056b673

First import of vendor version
author Peter Gervai <grin@grin.hu>
date Tue, 10 Mar 2009 13:49:58 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/srvrlib/db.h	Tue Mar 10 13:49:58 2009 +0100
@@ -0,0 +1,585 @@
+/* Distributed Checksum Clearinghouse database definitions
+ *
+ * Copyright (c) 2008 by Rhyolite Software, LLC
+ *
+ * This agreement is not applicable to any entity which sells anti-spam
+ * solutions to others or provides an anti-spam solution as part of a
+ * security solution sold to other entities, or to a private network
+ * which employs the DCC or uses data provided by operation of the DCC
+ * but does not provide corresponding data to other users.
+ *
+ * Permission to use, copy, modify, and distribute this software without
+ * changes for any purpose with or without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice appear in all
+ * copies and any distributed versions or copies are either unchanged
+ * or not called anything similar to "DCC" or "Distributed Checksum
+ * Clearinghouse".
+ *
+ * Parties not eligible to receive a license under this agreement can
+ * obtain a commercial license to use DCC by contacting Rhyolite Software
+ * at sales@rhyolite.com.
+ *
+ * A commercial license would be for Distributed Checksum and Reputation
+ * Clearinghouse software.  That software includes additional features.  This
+ * free license for Distributed ChecksumClearinghouse Software does not in any
+ * way grant permision to use Distributed Checksum and Reputation Clearinghouse
+ * software
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC
+ * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Rhyolite Software DCC 1.3.103-1.139 $Revision$
+ */
+
+#ifndef DB_H
+#define DB_H
+
+#include "srvr_defs.h"
+#include <math.h>
+
+extern u_char grey_on;
+
+#define DB_DCC_NAME	"dcc_db"
+#define DB_GREY_NAME	"grey_db"
+#define DB_HASH_SUFFIX  ".hash"
+#define DB_LOCK_SUFFIX	".lock"
+
+#define WHITELIST_NM(g)	    ((g) ? "grey_whitelist" : "whitelist")
+
+#define DB_VERSION3_STR "DCC checksum database version 3"
+#define DB_VERSION4_STR "DCC checksum database version 4"
+#define DB_VERSION5_STR "DCC checksum database version 5"
+/* tighten DB_EX_SEC in the next version */
+#define DB_VERSION_STR  DB_VERSION5_STR
+
+#define HASH_MAGIC_STR   "DCC hash 6"
+
+/* hash table indeces are only 32 bits */
+#define MAX_HASH_ENTRIES    0xffffffff
+
+#define MIN_CLEAN_HASH_ENTRIES  1024	/* run dbclean at this size */
+#define MIN_HASH_ENTRIES    (8*MIN_CLEAN_HASH_ENTRIES)
+#define DEF_HASH_ENTRIES    (6*1024*1024)
+#define MIN_HASH_DIVISOR    ((MIN_HASH_ENTRIES*7)/8)
+
+
+#define DB_CP3(x,v) do {u_int32_t _v = v; (x)[0] = _v>>16;		\
+    (x)[1] = _v>>8; (x)[2] = _v;} while (0)
+#define DB_CP4(x,v) do {u_int32_t _v = v; (x)[0] = _v>>24;		\
+    (x)[1] = _v>>16; (x)[2] = _v>>8; (x)[3] = _v;} while (0)
+#define DB_EX3(x) ((((u_int32_t)(x)[0])<<16) + ((x)[1]<<8) + (x)[2])
+#define DB_EX4(x) ((((u_int32_t)(x)[0])<<24) + (((u_int32_t)(x)[1])<<16) \
+		   + ((x)[2]<<8) + (x)[3])
+/* the least significant byte should be tested first */
+#define DB_ZERO3(x) ((x)[2] == 0 && (x)[1] == 0 && (x)[0] == 0)
+#define DB_ZERO4(x) ((x)[3] == 0 && (x)[2] == 0 && (x)[1] == 0 && (x)[0] == 0)
+
+
+/* a single checksum in a database record */
+typedef u_char      DB_TGTS[3];		/* a compressed count */
+typedef u_int64_t   DB_PTR;		/* database record offset */
+typedef u_int32_t   DB_PTR_C;		/*      compressed by DB_PTR_CP() */
+typedef struct {
+    DB_PTR_C    prev;			/* previous record for this checksum */
+    DB_TGTS     tgts;			/* accumulated reported targets */
+    DCC_CK_TYPE_B type_fgs;
+#    define      DB_CK_FG_OBS	0x80    /* obsolete report of a checksum */
+/* #    define	 DB_CK_	0x40		   once used */
+#    define	 DB_CK_MASK	0x0f
+#    define	 DB_CK_OBS(ck)	((ck)->type_fgs & DB_CK_FG_OBS)
+#    define      DB_CK_TYPE(ck)	((DCC_CK_TYPES)((ck)->type_fgs & DB_CK_MASK))
+    DCC_SUM     sum;
+} DB_RCD_CK;
+#define DB_TGTS_CK_SET(ck,v) DB_CP3((ck)->tgts,v)
+#define DB_TGTS_CK(ck) DB_EX3((ck)->tgts)
+
+/* shape of a checksum database entry */
+typedef struct {
+    DCC_TS      ts;			/* original server's creation date */
+    DCC_SRVR_ID srvr_id_auth;		/* initial server & client auth bit */
+#    define	 DB_RCD_ID(r)	((r)->srvr_id_auth & ~DCC_SRVR_ID_AUTH)
+    DB_TGTS     tgts_del;		/* # target addresses or delete flag */
+    u_char      fgs_num_cks;		/* # of cksums | flags */
+#    define      DB_RCD_FG_TRIM	    0x80    /* some checksums deleted */
+#    define	 DB_RCD_FG_SUMRY    0x40    /* fake summary record */
+#    define	 DB_RCD_FG_DELAY    0x20    /* delayed for fake summary */
+#    define	 DB_RCD_TRIMMED(r)  ((r)->fgs_num_cks & DB_RCD_FG_TRIM)
+#    define	 DB_RCD_SUMRY(r)    ((r)->fgs_num_cks & DB_RCD_FG_SUMRY)
+#    define	 DB_RCD_DELAY(r)    ((r)->fgs_num_cks & DB_RCD_FG_DELAY)
+#    define      DB_NUM_CKS(r)	    ((r)->fgs_num_cks & DB_CK_MASK)
+    DB_RCD_CK   cks[DCC_DIM_CKS];
+} DB_RCD;
+
+#define DB_RCD_HDR_LEN (ISZ(DB_RCD) - ISZ(DB_RCD_CK)*DCC_DIM_CKS)
+#define DB_RCD_LEN(r) (DB_RCD_HDR_LEN + DB_NUM_CKS(r) * ISZ(DB_RCD_CK))
+#define DB_RCD_LEN_MAX sizeof(DB_RCD)
+
+#define DB_TGTS_RCD_SET(r,v) DB_CP3((r)->tgts_del,v)
+#define DB_TGTS_RCD_RAW(r) DB_EX3((r)->tgts_del)
+static inline DCC_TGTS
+DB_TGTS_RCD(const DB_RCD *r)
+{
+	DCC_TGTS e = DB_TGTS_RCD_RAW(r);
+	return e == DCC_TGTS_DEL ? 0 : e;
+}
+
+/* this allows database of up to 48 GBytes */
+#define DB_PTR_MULT	    ((DB_PTR)12)    /* gcd of all sizes of DB_RCD */
+#define DB_PTR_CP(v)	    ((u_int32_t)((v) / DB_PTR_MULT))
+#define DB_PTR_EX(x)	    ((x) * DB_PTR_MULT)
+
+/* The kludge to speed conversion of database addresses to page numbers
+ * and offsets on 32-bit systems */
+#define DB_PTR_SHIFT 8
+#ifdef HAVE_64BIT_LONG
+#define DB_PTR2PG_NUM(p,s) ((p) / (s))
+#else
+#define DB_PTR2PG_NUM(p,s) ((u_int32_t)((p) >> DB_PTR_SHIFT)		\
+			    / (s >> DB_PTR_SHIFT))
+#endif
+
+#define DB_PTR_NULL	    0
+#define DB_PTR_BASE	    ISZ(DB_HDR)
+#define DB_PTR_MAX	    DB_PTR_EX((((DB_PTR)1)<<(sizeof(DB_PTR_C)*8)) -1)
+#define DB_PTR_BAD	    (DB_PTR_MAX+1)
+#define DB_PTR_IS_BAD(l)    ((l) < DB_PTR_BASE || (l) >= DB_PTR_MAX)
+
+
+typedef DCC_TS DB_SN;			/* database serial number */
+
+/* non-spam expiration */
+#define DB_EXPIRE_SECS_DEF	    (24*60*60)
+#define DB_EXPIRE_SECS_MAX	    DCC_MAX_SECS
+#define DB_EXPIRE_SECS_MIN	    (60*60)
+#define DB_EXPIRE_SECS_DEF_MIN	    (2*60*60)
+/* spam expiration */
+#define DB_EXPIRE_SPAMSECS_DEF	    (30*24*60*60)
+#define DB_EXPIRE_SPAMSECS_DEF_MIN  (1*24*60*60)
+#define DB_EXPIRE_REP_SECS_DEF	    DB_EXPIRE_SECS_DEF
+#define	DB_EXPIRE_REP_SPAMSECS_DEF  DB_EXPIRE_SPAMSECS_DEF
+/* keep server-ID declarations a week longer than reputations so that they
+ * will be first to be flooded */
+#define DB_EXPIRE_SRVR_ID_SECS	    (DB_EXPIRE_REP_SPAMSECS_DEF+7*24*60*60)
+
+/* re-announce spam this often */
+#define DCC_OLD_SPAM_SECS   (DB_EXPIRE_SPAMSECS_DEF_MIN/2)
+
+
+/* seconds to greylist or delay new mail messages
+ *  RFC 2821 says SMTP clients should wait at least 30 minutes to retry,
+ *  but 15 minutes seems more common than 30 minutes.  Many retry after
+ *  only 5 minutes, and some after only 1 (one!) second.  However,
+ *  many of those that retry after a few seconds keep trying for a minute
+ *  or two. */
+#define DEF_GREY_EMBARGO    270
+#define MAX_GREY_EMBARGO    (24*60*60)
+
+#define DEF_GREY_WINDOW	    (7*24*60*60)    /* wait as long as this */
+#define MAX_GREY_WINDOW	    (10*24*60*60)
+#define DEF_GREY_WHITE	    (63*24*60*60)   /* remember this long */
+#define MAX_GREY_WHITE	    DB_EXPIRE_SECS_MAX
+
+
+typedef struct {
+    DCC_TS      all;
+    DCC_TS      spam;
+} DB_EX_TS_TYPE;
+typedef DB_EX_TS_TYPE DB_EX_TS[DCC_DIM_CKS];
+typedef DCC_TS	DB_SPAM_EX_TS[DCC_DIM_CKS];
+typedef struct {
+    DCC_TGTS	unused;
+    int32_t	all;			/* allsecs */
+    int32_t	spam;			/* spamsecs */
+} DB_EX_SEC;
+typedef DB_EX_SEC DB_EX_SECS[DCC_DIM_CKS];
+
+#define DCC_CK_OK_GREY_CLNT(t) ((t) > DCC_CK_INVALID			    \
+				&& t <= DCC_CK_G_TRIPLE_R_BULK)
+#define DCC_CK_OK_GREY_FLOD(t) ((t) == DCC_CK_BODY			    \
+				|| ((t) >= DCC_CK_G_MSG_R_TOTAL		    \
+				    && (t) <= DCC_CK_FLOD_PATH)		    \
+				|| ((t) == DCC_CK_IP && grey_weak_ip))
+
+#define DEF_FLOD_THOLDS(g,t) ((g) ? 1					    \
+			      : t == DCC_CK_SRVR_ID ? 1 : BULK_THRESHOLD)
+
+#define DCC_CK_OK_DCC_CLNT(g,t) ((t) > DCC_CK_INVALID			    \
+				 && (t) <= DCC_CK_G_TRIPLE_R_BULK	    \
+				 && ((g)|| (t) <= DCC_CK_FUZ2))
+#define DCC_CK_OK_DB(g,t) ((t) > DCC_CK_INVALID && t <= DCC_CK_TYPE_LAST    \
+			   && ((g) || ((t) != DCC_CK_G_MSG_R_TOTAL	    \
+				       && (t) != DCC_CK_G_TRIPLE_R_BULK)))
+#define DCC_CK_OK_FLOD(g,t) ((g) ? DCC_CK_OK_GREY_FLOD(t)		    \
+			     : ((t) > DCC_CK_INVALID			    \
+				&& ((t) <= DCC_CK_FUZ2			    \
+				    || (t) == DCC_CK_FLOD_PATH		    \
+				    || (t) == DCC_CK_SRVR_ID)))
+
+
+typedef u_int32_t DB_NOKEEP_CKS;	/* bitmask of ignored checksums */
+#define DB_SET_NOKEEP(map,t)	((map) |= (1<<(t)))
+#define DB_RESET_NOKEEP(map,t)	((map) &= ~(1<<(t)))
+#define DB_TEST_NOKEEP(map,t)	((map) & (1<<(t)))
+
+/* relative fuzziness of checksums */
+#define DCC_CK_FUZ_LVL_NO   1		/* least fuzzy */
+#define DCC_CK_FUZ_LVL1	    2		/* somewhat fuzzy */
+#define DCC_CK_FUZ_LVL2	    3		/* fuzzier */
+#define DCC_CK_FUZ_LVL3	    4		/* reputations */
+#define DCC_CK_FUZ_LVL_REP  DCC_CK_FUZ_LVL3
+extern const u_char *db_ck_fuzziness;
+
+
+typedef DB_PTR		    DB_HOFF;	/* byte offset into hash table */
+typedef u_int32_t	    DB_HADDR;	/* index of a hash table entry */
+typedef u_char DB_HADDR_C[4];		/* compressed hash chain link */
+#define DB_HADDR_CP(x,v)    DB_CP4(x,v)
+#define DB_HADDR_EX(x)      DB_EX4(x)
+#define DB_HADDR_NULL       0		/* no-answer from hashing & linking */
+#define DB_HADDR_C_NULL(x)  DB_ZERO4(x)
+#define DB_HADDR_INVALID(h) ((h) < DB_HADDR_BASE || (h) >= db_hash_len)
+#define DB_HADDR_C_INVALID(h) DB_HADDR_INVALID(DB_HADDR_EX(h))
+
+typedef u_char DB_PTR_HC[4];
+#define DB_HPTR_CP(x,v) {u_int32_t _v = DB_PTR_CP(v);			\
+    (x)[0] = _v>>24; (x)[1] = _v>>16; (x)[2] = _v>>8; (x)[3] = _v;}
+#define DB_HPTR_EX(x) DB_PTR_EX(((x)[0]<<24) + ((x)[1]<<16)		\
+				+ ((x)[2]<<8) + (x)[3])
+
+
+/* shape of the magic string that starts a database */
+typedef char DB_VERSION_BUF[64];
+typedef struct {
+    DB_VERSION_BUF version;		/* see DB_VERSION_STR */
+    DB_PTR      db_csize;		/* size of database contents in bytes */
+    u_int32_t   pagesize;		/* size of 1 DB buffer */
+    DB_SN       sn;			/* creation or expiration serial # */
+    time_t	cleared;		/* when created */
+    time_t	cleaned;		/* real instead of repair cleaning */
+    time_t	cleaned_cron;		/* cleaned by cron */
+    DB_SPAM_EX_TS ex_spam;		/* recent expiration timestamps */
+    DB_SPAM_EX_TS ex_all;		/* recent expiration timestamps */
+    DB_EX_SECS  ex_secs;		/* recent expiration thresholds */
+    DB_NOKEEP_CKS nokeep_cks;		/* ignore these checksums */
+    u_int	flags;
+#    define DB_PARM_FG_GREY	0x01    /* greylist database */
+#    define DB_PARM_FG_CLEARED	0x02    /* new file */
+#    define DB_PARM_EXP_SET	0x04	/* have explicit expiration durations */
+    DB_PTR	old_db_csize;		/* size at last cleaning */
+    DB_PTR	db_added;		/* bytes previously added to database */
+    DB_HADDR	hash_used;		/* recent of entries used */
+    DB_HADDR	old_hash_used;		/* entries used at last cleaning */
+    DB_HADDR	hash_added;		/* entries added */
+    time_t	rate_secs;		/* denominator of rates */
+#    define	 DB_MIN_RATE_SECS (12*60*60)
+#    define	 DB_MAX_RATE_SECS (14*24*60*60)
+    time_t	last_rate_sec;
+    DB_HADDR	old_kept_cks;		/* reported checksums at cleaning */
+} DB_PARMS;
+typedef union {
+    DB_PARMS	p;
+    char	c[256*3];
+} DB_HDR;
+
+#ifdef DB_VERSION4_STR
+typedef struct {
+    DB_VERSION_BUF version;
+    DB_PTR      db_csize;
+    u_int32_t   pagesize;
+    DB_SN       sn;
+    time_t	cleared;
+    time_t	cleaned;
+    time_t	cleaned_cron;
+    DB_SPAM_EX_TS ex_spam;
+    DB_EX_SECS  ex_secs;
+    DB_NOKEEP_CKS nokeep_cks;
+    u_int	flags;
+    DB_PTR	old_db_csize;
+    DB_PTR	db_added;
+    DB_HADDR	hash_used;
+    DB_HADDR	old_hash_used;
+    DB_HADDR	hash_added;
+    time_t	rate_secs;
+    time_t	last_rate_sec;
+    DB_HADDR	old_kept_cks;
+} DB_V4_PARMS;
+#endif
+#ifdef DB_VERSION3_STR
+typedef struct {
+    DB_VERSION_BUF version;
+    DB_PTR      db_csize;
+    u_int32_t   pagesize;
+    DB_SN       sn;
+    DB_SPAM_EX_TS ex_spam;
+    DB_EX_SECS  ex_secs;
+    DB_NOKEEP_CKS nokeep_cks;
+    DCC_TGTS    unused[DCC_DIM_CKS];
+    u_int	flags;
+#    define DB_PARM_V3_FG_GREY		0x01
+#    define DB_PARM_V3_FG_SELF_CLEAN	0x02
+#    define DB_PARM_V3_FG_SELF_CLEAN2	0x04
+#    define DB_PARM_V3_FG_CLEARED	0x08
+    DB_PTR	old_db_csize;
+    DB_PTR	db_added;
+    DB_HADDR	hash_used;
+    DB_HADDR	old_hash_used;
+    DB_HADDR	hash_added;
+    time_t	rate_secs;
+    time_t	last_rate_sec;
+    DB_HADDR	old_kept_cks;
+} DB_V3_PARMS;
+#endif
+
+/* shape of a database hash table entry */
+typedef struct {
+    DB_HADDR_C  fwd, bak;		/* hash collision chain */
+    u_char	hv_type[2];		/* checksum type + some hash bits */
+#    define	 HE_TYPE(e)	((DCC_CK_TYPES)((e)->hv_type[0] & 0xf))
+#    define	 HE_IS_FREE(e)	((e)->hv_type[0] == 0)
+#    define	 HE_MERGE(e,t,s) ((e)->hv_type[0] = ((((s)[0])<<4)+t),	\
+				  (e)->hv_type[1] = (s)[1])
+#    define	 HE_CMP(e,t,s)	((e)->hv_type[1] == (s)[1]		\
+				 && (e)->hv_type[0] ==(u_char)((((s)[0])<<4)+t))
+
+    DB_PTR_HC   rcd;			/* record for this hash table entry */
+} HASH_ENTRY;
+
+
+
+typedef union {
+    HASH_ENTRY	h[8];			/* this must be larger than following */
+    struct {
+	char	    magic[16];
+	u_int	    flags;
+#	 define	     HASH_CTL_FG_CLEAN	0x01	/* consistent */
+#	 define	     HASH_CTL_FG_NOSYNC	0x02	/* pushed to stable storage */
+	DB_HADDR    free_fwd;		/* hash table internal free list */
+	DB_HADDR    free_bak;
+#	 define	     FREE_HADDR_END 1
+	DB_HADDR    len;		/* size of file in entries */
+	DB_HADDR    used;		/* entries actually used */
+	DB_HADDR    divisor;		/* hash modulus */
+	DB_PTR	    db_csize;		/* size of the database file */
+	time_t	    synced;
+    } s;
+} HASH_CTL;
+
+
+#define DB_HADDR_BASE	((DB_HADDR)((sizeof(HASH_CTL)+sizeof(HASH_ENTRY)-1) \
+				    / sizeof(HASH_ENTRY)))
+#define HADDR2LEN(l)	((int)((l)-DB_HADDR_BASE))  /* offset to length */
+
+
+/* control a block of mapped memory */
+typedef u_int16_t DB_PG_NUM;
+typedef u_int32_t DB_PG_OFF;
+typedef enum {
+    DB_BUF_TYPE_FREE = 0,
+    DB_BUF_TYPE_HASH,
+    DB_BUF_TYPE_DB
+} DB_BUF_TYPE;
+#ifdef HAVE_64BIT_LONG
+typedef u_int64_t DB_BUF_FM;
+#else
+typedef u_int32_t DB_BUF_FM;
+#endif
+#define DB_BUF_NUM_PARTS    (8*ISZ(DB_BUF_FM))
+#define PART2BIT(part)	    (((DB_BUF_FM)1) << (part))
+typedef struct db_buf {
+    struct db_buf *fwd, *bak, **hash;
+    struct db_buf *older, *newer;
+    union {
+	void	    *v;
+	HASH_ENTRY  *h;
+	char	    *c;
+    } buf;
+    DB_PG_NUM	pg_num;
+    int		lock_cnt;
+    DB_BUF_TYPE	buf_type;
+    DB_BUF_FM	flush;
+    DB_BUF_FM	flush_urgent;
+    struct {
+	char	*lo, *hi;
+    } ranges[DB_BUF_NUM_PARTS];
+    u_char	flags;
+#    define	 DB_BUF_FG_USE_WRITE	0x01    /* use write() */
+#    define	 DB_BUF_FG_EXTENSION	0x02	/* new page in file */
+} DB_BUF;
+
+/* context for searching for or adding a record */
+typedef struct {
+    union {				/* pointer to data in buffer */
+	void	    *v;
+	HASH_ENTRY  *h;
+	char	    *c;
+	DB_RCD      *r;
+	DB_PARMS    *parms;
+	HASH_CTL    *vals;
+    } d;
+    union {				/* database address */
+	DB_HADDR    haddr;
+	DB_PTR      rptr;
+    } s;
+    DB_BUF      *b;
+} DB_STATE;
+
+/* see db_close() before changing this */
+typedef struct {
+    DB_STATE	rcd;			/* must be first */
+    DB_STATE	rcd2;
+    DB_STATE	sumrcd;
+    DB_STATE	hash;
+    DB_STATE	free;
+    DB_STATE	tmp;
+    DB_STATE	db_parms;
+    DB_STATE	hash_ctl;		/* hash control info; must be last */
+} DB_STATES;
+extern DB_STATES db_sts;
+
+extern int db_failed_line;
+extern const char *db_failed_file;
+#define DB_ERROR_MSG(s) db_error_msg(__LINE__,__FILE__, "%s", s)
+#define DB_ERROR_MSG2(s1,s2) db_error_msg(__LINE__,__FILE__, "%s: %s", s1,s2)
+
+extern struct timeval db_time;
+#define DB_IS_TIME(tgt,lim) DCC_IS_TIME(db_time.tv_sec,tgt,lim)
+#define DB_ADJ_TIMER(tgt,lim,new) DCC_ADJ_TIMER(db_time.tv_sec,tgt,lim,new)
+
+extern u_char db_minimum_map;		/* this is dccd & dbclean is running */
+extern int db_fd, db_hash_fd;
+extern DCC_PATH db_nm, db_hash_nm;
+extern struct timeval db_locked;	/* 0 or when database was locked */
+extern int db_debug;
+extern DB_SN db_sn;
+
+extern DB_HOFF db_hash_fsize;		/* size of hash table file */
+extern DB_HADDR db_hash_len;		/* # of hash table entries */
+extern DB_HADDR db_hash_divisor;	/* modulus */
+extern DB_HADDR db_hash_used;		/* # of hash table entries in use */
+extern u_int db_hash_page_len;		/* # of HASH_ENTRY's per buffer */
+extern DB_HADDR db_max_hash_entries;	/* max size of hash table */
+extern DB_PTR db_fsize;			/* size of database file */
+extern DB_PTR db_csize;			/* size of database contents in bytes */
+extern const DB_VERSION_BUF db_version_buf;
+extern DB_PARMS db_parms;
+extern DCC_TGTS db_tholds[DCC_DIM_CKS];
+extern u_int db_pagesize;		/* size of 1 DB buffer */
+extern u_int db_page_max;		/* only padding after this */
+extern char db_window_size_str[];	/* size of mmap() window */
+
+typedef struct {
+    u_int   db_mmaps;
+    u_int   hash_mmaps;
+    u_int   adds;			/* reports added */
+} DB_STATS;
+extern DB_STATS db_stats;
+
+
+/* If the two files were smaller than the typical mmap() limit of a fraction
+ * of a GByte, they could be mmap()'ed directly.  They are often too large.
+ *
+ * Use a modest pool of buffers to map the DB hash table and the database
+ * itself.
+ * Each access to the files could be with a single, common buffer,
+ * but that would involve many more mmap() system calls.
+ * Most of the DB hash table is expected to fit in the application's memory.
+ *
+ * Use the same modest pool of buffers to map the database itself.
+ * References to the database have a lot of locality, so the commonly used
+ * checksums and counts should remain in memory.
+ *
+ * Common operating system limits on the number of mapped segments are
+ * below 256 and so that is a bound on DB_BUF_MAX */
+#define DB_BUF_MAX 128			/* maximum # of buffers */
+#define DB_BUF_PARTS_MAX    (DB_BUF_MAX*DB_BUF_NUM_PARTS)
+
+/* enough buffers so max simultaneous pointers can be satisfied */
+#define DB_BUF_MIN (sizeof(DB_STATES)/sizeof(DB_STATE) + 2)
+
+extern int db_buf_total;		/* total # of db buffers */
+extern DB_PTR db_max_rss;		/* maximum db resident set size */
+extern DB_PTR db_max_byte;
+
+
+extern time_t db_need_flush_secs;
+#define DB_NEED_FLUSH_SECS	5
+#define DB_STALE_SECS		(30*60)	/* limit on buffer staleness */
+#define	DB_FLUSHES		(DB_STALE_SECS / DB_NEED_FLUSH_SECS)
+#define DB_PARTS_PER_FLUSH	((DB_BUF_PARTS_MAX + DB_FLUSHES-1) / DB_FLUSHES)
+#define DB_URGENT_NEED_FLUSH_SECS   120
+
+
+/* fix configure script if this changes */
+#define DB_MIN_MIN_MBYTE    32
+#define DB_DEF_MIN_MBYTE    64		/* a reasonable tiny default */
+#define DB_PAD_MBYTE	    128		/* RAM for rate limiting blocks etc */
+#define DB_PAD_BYTE	(DB_PAD_MBYTE*1024*1024)
+#define DB_MAX_2G_MBYTE	(2048-DB_PAD_MBYTE) /* <2 GByte on 32 bit machines */
+/* the database cannot exceed 48 GBytes because of DB_PTR_CP */
+#define MAX_MAX_DB_MBYTE    (48*1024)
+/*	fix INSTALL.html if those change */
+
+
+/* srvr/db.c */
+extern void db_failure(int, const char *, int, DCC_EMSG,
+		       const char *, ...) PATTRIB(5,6);
+extern void db_error_msg(int, const char *, const char *, ...) PATTRIB(3,4);
+extern void db_set_flush(DB_STATE *, u_char, u_int);
+#define SET_FLUSH_RCD(st,u)	db_set_flush(st,u, DB_RCD_LEN((st)->d.r))
+#define SET_FLUSH_RCD_HDR(st,u)	db_set_flush(st,u, DB_RCD_HDR_LEN)
+#define SET_FLUSH_HE(st)	db_set_flush(st, 0, sizeof(HASH_ENTRY))
+#define SET_FLUSH_HCTL(u)   db_set_flush(&db_sts.hash_ctl,u, sizeof(HASH_CTL))
+extern void rel_db_states(void);
+extern u_char db_unload(DCC_EMSG, u_char);
+extern u_char db_flush_db(DCC_EMSG);
+extern u_char make_clean(u_char);
+extern u_char db_close(int);
+extern void db_stop(void);
+extern u_char lock_dbclean(DCC_EMSG, const char *);
+extern void unlock_dbclean(void);
+extern u_int db_get_pagesize(u_int, u_int);
+extern u_char db_buf_init(u_int, u_int);
+typedef u_char DB_OPEN_MODES;
+# define DB_OPEN_RDONLY		    0x01
+# define DB_OPEN_LOCK_WAIT	    0x02    /* wait to get lock */
+# define DB_OPEN_LOCK_NOWAIT	    0x04    /* get lock but don't wait */
+# define DB_OPEN_MMAP_WRITE	    0x08    /* use write() instead of mmap() */
+# define DB_OPEN_MMAP_WRITE_NOSYNC  0x10    /*	    if no mmap(NOSYNC) */
+extern u_char db_open(DCC_EMSG, int, const char *, DB_HADDR, DB_OPEN_MODES);
+extern u_char db_flush_parms(DCC_EMSG );
+#define DB_IS_LOCKED() (db_locked.tv_sec != 0)
+extern int db_lock(void);
+extern u_char db_unlock(void);
+extern void db_flush_needed(void);
+extern DCC_TGTS db_sum_ck(DCC_TGTS, DCC_TGTS, DCC_CK_TYPES);
+extern const char *db_ptr2str(DB_PTR);
+extern const char *size2str(char *, u_int, double, u_char);
+extern double db_add_rate(const DB_PARMS *, u_char);
+extern DB_NOKEEP_CKS def_nokeep_cks(void);
+extern void set_db_tholds(DB_NOKEEP_CKS);
+extern u_char db_map_rcd(DCC_EMSG, DB_STATE *, DB_PTR, int *);
+extern DB_RCD_CK *db_find_ck(DCC_EMSG, DB_RCD *, DB_PTR, DCC_CK_TYPES);
+extern DB_RCD_CK *db_map_rcd_ck(DCC_EMSG, DB_STATE *, DB_PTR, DCC_CK_TYPES);
+extern DB_HADDR get_db_hash_divisor(DB_HADDR);
+extern DB_HADDR db_hash(DCC_CK_TYPES, const DCC_SUM);
+typedef enum {
+    DB_FOUND_SYSERR=0,			/* fatal error */
+    DB_FOUND_LATER,			/* out of specified hash table range */
+    DB_FOUND_IT,
+    DB_FOUND_EMPTY,			/* home slot empty */
+    DB_FOUND_CHAIN,			/* not in chain--have last entry */
+    DB_FOUND_INTRUDER			/* intruder in home slot */
+} DB_FOUND;
+extern DB_FOUND db_lookup(DCC_EMSG, DCC_CK_TYPES, const DCC_SUM,
+			  DB_HADDR, DB_HADDR, DB_STATE *,
+			  DB_STATE *, DB_RCD_CK **);
+extern u_char db_link_rcd(DCC_EMSG, DB_HADDR, DB_HADDR);
+extern DB_PTR db_add_rcd(DCC_EMSG, const DB_RCD *);
+
+#endif /* DB_H */