Mixmaster Message Drops

Public <Anonymous_Account> remailer at anon.xg.nu
Wed Aug 8 13:27:14 PDT 2001


My studies show about 1 chance in 20 that any particular running
remailer will drop a message.  This is based on sending a bunch of
messages through chains of remailers of varying length and seeing how
many arrive in a day or so, and then calculating the average
probability.

Note that in a chain of twenty remailers this causes many messages to
be dropped.  Even if we achieve a reliability rate of 1 in 100,000,
this means about 1 in 5000 messages will be lost through a chain of 20
remailers.

For some reason remailer culture has accepted message drops as normal.
They aren't normal.  There isn't any reason why a remailer should be
any less reliable than a mail server.  I estimate mail servers are far
more reliable than 1 loss in 100,000 messages.

One possibility is that some of my tests went through remailers that
are just down.  This hasn't been ruled out beyond any reasonable
doubt, but it appears that the drops are occuring in remailers which
are still carrying traffic.

I did an extensive series of tests with an internal mixmaster network
running Mixmaster 2.0.3.  I had to fool around with it, but I was able
to run many hundreds of messages through chains of 20 hops without a
single message drop.

The core software appears to be solid (unless bugs have been
introduced into more recent releases ;-), but the setup needs to be
tweaked.

The practice of putting something like this into .forward is a problem:
"|/usr9/loki/Devel/Mix/mixmaster -R >> /usr/spool/mail/username"

If too many messages come in at once this brings a machine to its
knees because it runs many mixmaster processes at once.  There may
also be a bug in mixmaster which is only expressed when many mixmaster
processes simultaneously tries to queue a message.

FYI, this also creates an easy DoS on a mixmaster node.  Just send the
node a bunch of messages which loop back into itself over and over
again.  This should rapidly cause sendmail to spawn many mixmaster
processes and lock up the machine.  I haven't tried this on anybody
else's mixmaster node.

The solution is to have a small program which puts incoming messages
into a spool file.  I've enclosed the perl script I used, which comes
with no guarantees and hasn't been tested all that much.  (It would be
nice if errors went to a log file instead of being bounced.)

The script copies the message into a file in the spool directory
starting with "temp".  Then it moves it to a file starting with
"spool".  The reason for the move is to guarantee that all "spool"
files are complete messages.  The time of creation is encoded in the
name so a processing program can get the files in order.

The other pieces needed are a small perl script which monitors the
spool directory and calls mixmaster to queue up each file and another
process which calls mixmaster repeatedly to process the queued
messages.

This setup causes no more than two mixmaster processes to run at a
time and is more robust.  Would somebody mind polling the remailer
operators to see how many are running mixmaster directly from
.forward?

I suspect this is most of the problem.  If it isn't, we need to
eliminate it before pursuing the next suspect.

---cut here------cut here------cut here------cut here------cut here------cut here---
#!/usr/bin/perl -w

# This code is in the public domain.

# Put in a .forward file.  Spools mail into a directory for processing
# by something else.

require 5;
use strict;

use English;

my(@pwvals) = getpwuid($UID);
my($homedir) = $pwvals[7];
my($spooldir) = "$homedir/spool";

die "Home directory doesn't exist." if ! -e $homedir;
die "Home directory isn't a directory." if ! -d $homedir;

die "$spooldir doesn't exist." if ! -e $spooldir;
die "$spooldir is not a directory." if ! -d $spooldir;

my($now) = time;
my($now_string);
if( length($now) < 12 ) {
    $now_string = ('0' x (12 - length($now))) . $now;
}

my($temppath) = "$spooldir/temp.$now_string.$$";
die "Amazingly, $temppath already exists." if -e $temppath;

open(SPOOLFILE, ">$temppath")
    or die "Could not open $temppath for writing.\n";
while(<>) {
    print SPOOLFILE $_;
}
close(SPOOLFILE);

my($spoolpath) = "$spooldir/spool.$now_string.$$";
die "Amazingly, $spoolpath already exists." if -e $spoolpath;

if( ! rename $temppath, $spoolpath ) {
    die "Could not rename $temppath to $spoolpath.";
}

# Let sendmail know everything is fine.
exit(0);





More information about the cypherpunks-legacy mailing list