Author: hjp
Date: Sun Sep 2 03:50:23 2007
New Revision: 785
Modified:
trunk/lib/Qpsmtpd/Connection.pm
trunk/lib/Qpsmtpd/SMTP.pm
trunk/lib/Qpsmtpd/Transaction.pm
trunk/qpsmtpd-forkserver
Log:
New id scheme: Start with a unique id for the Qpsmtpd::SMTP object,
then derive ids for connections and transactions from that via
simple counters.
Modified: trunk/lib/Qpsmtpd/Connection.pm
==============================================================================
--- trunk/lib/Qpsmtpd/Connection.pm (original)
+++ trunk/lib/Qpsmtpd/Connection.pm Sun Sep 2 03:50:23 2007
@@ -1,9 +1,6 @@
package Qpsmtpd::Connection;
use strict;
-use Sys::Hostname;
-use Time::HiRes qw(gettimeofday);
-
# All of these parameters depend only on the physical connection,
# i.e. not on anything sent from the remote machine. Hence, they
# are an appropriate set to use for either start() or clone(). Do
@@ -18,27 +15,7 @@
relay_client
);
-my $SALT_HOST = crypt(hostname, chr(65+rand(57)).chr(65+rand(57)));
-$SALT_HOST =~ tr/A-Za-z0-9//cd;
-
-sub new_id {
- my $self = shift;
- # Generate unique id
- # use gettimeofday for microsec precision
- # add in rand() in case gettimeofday clock is slow (e.g. bsd?)
- # add in $$ in case srand is set per process
- my ($start, $mstart) = gettimeofday();
- my $id = sprintf("%d.%06d.%s.%d.%d",
- $start,
- $mstart,
- $SALT_HOST,
- rand(10000),
- $$,
- );
- $self->{_id} = $id;
-
-}
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
@@ -61,10 +38,16 @@
sub id {
my $self = shift;
- $self->new_id unless $self->{_id};
+ $self->{_id} = shift if @_;
$self->{_id};
}
+sub inc_id {
+ my $self = shift;
+ my ($qp_id, $count) = $self->{_id} =~ m/(.+)\.(\d+)/;
+ $self->{_id} = $qp_id . "." . ++$count;
+}
+
sub clone {
my $self = shift;
my $new = $self->new();
Modified: trunk/lib/Qpsmtpd/SMTP.pm
==============================================================================
--- trunk/lib/Qpsmtpd/SMTP.pm (original)
+++ trunk/lib/Qpsmtpd/SMTP.pm Sun Sep 2 03:50:23 2007
@@ -19,6 +19,8 @@
#use Data::Dumper;
use POSIX qw(strftime);
use Net::DNS;
+use Time::HiRes qw(gettimeofday);
+use Sys::Hostname;
# this is only good for forkserver
# can't set these here, cause forkserver resets them
@@ -37,10 +39,20 @@
my (%commands); @[EMAIL PROTECTED] = ('') x @commands;
# this list of valid commands should probably be a method or a set of methods
$self->{_commands} = \%commands;
-
$self;
}
+sub id {
+ my $self = shift;
+ unless ($self->{_id}) {
+ $self->{_id} = sprintf("%d.%06d.%s.%d",
+ gettimeofday,
+ unpack("H*", (gethostbyname(hostname))[4]),
+ $$);
+ }
+ return $self->{_id};
+}
+
sub command_counter {
my $self = shift;
$self->{_counter} || 0;
@@ -135,16 +147,27 @@
sub reset_transaction {
my $self = shift;
$self->run_hooks("reset_transaction") if $self->{_transaction};
- return $self->{_transaction} = Qpsmtpd::Transaction->new();
+ return $self->{_transaction} =
+ Qpsmtpd::Transaction->new(id => $self->connection->id . "." .
++$self->{_transaction_count});
}
sub connection {
my $self = shift;
@_ and $self->{_connection} = shift;
- return $self->{_connection} || ($self->{_connection} =
Qpsmtpd::Connection->new());
+ unless ($self->{_connection}) {
+ $self->{_connection} = Qpsmtpd::Connection->new();
+ $self->reset_connection;
+ }
+ return $self->{_connection};
}
+sub reset_connection {
+ my $self = shift;
+ $self->connection->id($self->id . "." . ++$self->{_connection_count});
+ $self->{_transaction_count} = 0;
+ $self->reset_transaction;
+}
sub helo {
my ($self, $line) = @_;
Modified: trunk/lib/Qpsmtpd/Transaction.pm
==============================================================================
--- trunk/lib/Qpsmtpd/Transaction.pm (original)
+++ trunk/lib/Qpsmtpd/Transaction.pm Sun Sep 2 03:50:23 2007
@@ -22,21 +22,7 @@
my $class = ref($proto) || $proto;
my %args = @_;
- # Generate unique id
- # use gettimeofday for microsec precision
- # add in a sequence in case gettimeofday clock is slow (e.g. alpha)
- # add in $$ to provide uniqueness per process/child
- my ($start, $mstart) = gettimeofday();
- my $seq = $SEQUENCE_ID++ % 10000;
- my $id = sprintf("%d.%06d.%s.%d.%d",
- $start,
- $mstart,
- $SALT_HOST,
- $seq,
- $$,
- );
-
- my $self = { _rcpt => [], started => $start, _id => $id };
+ my $self = { _rcpt => [], started => time, _id => $args{id} };
bless ($self, $class);
return $self;
}
Modified: trunk/qpsmtpd-forkserver
==============================================================================
--- trunk/qpsmtpd-forkserver (original)
+++ trunk/qpsmtpd-forkserver Sun Sep 2 03:50:23 2007
@@ -239,7 +239,7 @@
# get local/remote hostname, port and ip address
my ($port, $iaddr, $lport, $laddr, $nto_iaddr, $nto_laddr) =
Qpsmtpd::TcpServer::lrpip($server, $client, $hisaddr);
- $qpsmtpd->connection->new_id;
+ $qpsmtpd->reset_connection;
my ($rc, @msg) = $qpsmtpd->run_hooks("pre-connection",
remote_ip => $nto_iaddr,
remote_port => $port,