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,

Reply via email to