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;
|
package Qpsmtpd::Connection;
|
||||||
use strict;
|
use strict;
|
||||||
|
|
||||||
use Sys::Hostname;
|
|
||||||
use Time::HiRes qw(gettimeofday);
|
|
||||||
|
|
||||||
# All of these parameters depend only on the physical connection,
|
# All of these parameters depend only on the physical connection,
|
||||||
# i.e. not on anything sent from the remote machine. Hence, they
|
# i.e. not on anything sent from the remote machine. Hence, they
|
||||||
# are an appropriate set to use for either start() or clone(). Do
|
# are an appropriate set to use for either start() or clone(). Do
|
||||||
@ -18,27 +15,7 @@ my @parameters = qw(
|
|||||||
relay_client
|
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 {
|
sub new {
|
||||||
my $proto = shift;
|
my $proto = shift;
|
||||||
my $class = ref($proto) || $proto;
|
my $class = ref($proto) || $proto;
|
||||||
@ -61,10 +38,16 @@ sub start {
|
|||||||
|
|
||||||
sub id {
|
sub id {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
$self->new_id unless $self->{_id};
|
$self->{_id} = shift if @_;
|
||||||
$self->{_id};
|
$self->{_id};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub inc_id {
|
||||||
|
my $self = shift;
|
||||||
|
my ($qp_id, $count) = $self->{_id} =~ m/(.+)\.(\d+)/;
|
||||||
|
$self->{_id} = $qp_id . "." . ++$count;
|
||||||
|
}
|
||||||
|
|
||||||
sub clone {
|
sub clone {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $new = $self->new();
|
my $new = $self->new();
|
||||||
|
@ -19,6 +19,8 @@ use Mail::Header ();
|
|||||||
#use Data::Dumper;
|
#use Data::Dumper;
|
||||||
use POSIX qw(strftime);
|
use POSIX qw(strftime);
|
||||||
use Net::DNS;
|
use Net::DNS;
|
||||||
|
use Time::HiRes qw(gettimeofday);
|
||||||
|
use Sys::Hostname;
|
||||||
|
|
||||||
# this is only good for forkserver
|
# this is only good for forkserver
|
||||||
# can't set these here, cause forkserver resets them
|
# can't set these here, cause forkserver resets them
|
||||||
@ -37,10 +39,20 @@ sub new {
|
|||||||
my (%commands); @commands{@commands} = ('') x @commands;
|
my (%commands); @commands{@commands} = ('') x @commands;
|
||||||
# this list of valid commands should probably be a method or a set of methods
|
# this list of valid commands should probably be a method or a set of methods
|
||||||
$self->{_commands} = \%commands;
|
$self->{_commands} = \%commands;
|
||||||
|
|
||||||
$self;
|
$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 {
|
sub command_counter {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
$self->{_counter} || 0;
|
$self->{_counter} || 0;
|
||||||
@ -135,16 +147,27 @@ sub transaction {
|
|||||||
sub reset_transaction {
|
sub reset_transaction {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
$self->run_hooks("reset_transaction") if $self->{_transaction};
|
$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 {
|
sub connection {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
@_ and $self->{_connection} = 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 {
|
sub helo {
|
||||||
my ($self, $line) = @_;
|
my ($self, $line) = @_;
|
||||||
|
@ -22,21 +22,7 @@ sub start {
|
|||||||
my $class = ref($proto) || $proto;
|
my $class = ref($proto) || $proto;
|
||||||
my %args = @_;
|
my %args = @_;
|
||||||
|
|
||||||
# Generate unique id
|
my $self = { _rcpt => [], started => time, _id => $args{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 };
|
|
||||||
bless ($self, $class);
|
bless ($self, $class);
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ while (1) {
|
|||||||
# get local/remote hostname, port and ip address
|
# get local/remote hostname, port and ip address
|
||||||
my ($port, $iaddr, $lport, $laddr, $nto_iaddr, $nto_laddr) = Qpsmtpd::TcpServer::lrpip($server, $client, $hisaddr);
|
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",
|
my ($rc, @msg) = $qpsmtpd->run_hooks("pre-connection",
|
||||||
remote_ip => $nto_iaddr,
|
remote_ip => $nto_iaddr,
|
||||||
remote_port => $port,
|
remote_port => $port,
|
||||||
|
Loading…
Reference in New Issue
Block a user