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. git-svn-id: https://svn.perl.org/qpsmtpd/trunk@785 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
parent
85cd1aae2b
commit
af82701fff
@ -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 @@ my @parameters = qw(
|
||||
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 start {
|
||||
|
||||
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();
|
||||
|
@ -19,6 +19,8 @@ use Mail::Header ();
|
||||
#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 @@ sub new {
|
||||
my (%commands); @commands{@commands} = ('') 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 transaction {
|
||||
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) = @_;
|
||||
|
@ -22,21 +22,7 @@ sub start {
|
||||
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;
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ while (1) {
|
||||
# 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,
|
||||
|
Loading…
Reference in New Issue
Block a user