The Database Schema

The slowmilt milter uses Berkeley DB 4.1, which is not a relational database. Although two databases can be joined for bidirectional lookups, that approach was not used for slowmilt.

The slowmilt milter uses two databases:

The keys for the IP address database are IP addresses stored in binary in standard network byte order.

typedef unsigned long PRIMARY_KEY; /* IPv4 IP number in numeric binary */ The keys for the Events database are a combination of an IP address and a date/time, where the date/time is in binary in Unix time_t format.

typedef struct {
        PRIMARY_KEY     ip;
For version 1 of the database (where no version information is stored) the data for the IP address database is an ever growing array of date/time entries.

typedef PRIMARY_DATUM **PRIMARY_DATA; /* FIFO list of date/times */ The next version of the IP address database will use the zeroth date/time as a flag to signal such things as white-listing and aliases. In this next version, IP address will hold the version number.

The data for the Events database is a structure that looks like this:

# define MAX_MESSAGE_ID (256)
typedef struct {
        BITMAP          eventmap;       /* See the BIT_ definitions below */
        unsigned int    envrcpts;       /* excess envelope recipients */
        unsigned int    headrcpts;      /* excess header recipients */
        unsigned int    honeyrcpts;     /* total honey pot recipients */
        unsigned int    badrcpts;       /* total bad recipients */
        char            msgid[MAX_MESSAGE_ID];
The items in this datum structure (together) define a single event. See the standard event set for a description of what the items in this structure mean. Also see slow.h in the source distribution to understand the ordering of bits in eventmap.

Both databases together constitute the database. The database can be dumped to a file using the slowedit list command, and that text output can be later be fed back into the slowedit rebuild command to recreate the database.