Mail-SpamAssassin

 view release on metacpan or  search on metacpan

spamd/spamd.raw  view on Meta::CPAN

      if (!defined $nfound || $nfound < 0) {
        die "select failed on fd bit field $sel_mask_str: $!";
      } elsif (!$nfound) {
        die "no fd ready, fd bit field $sel_mask_str";
      }

      my(@ready_fd) =  # list of file descriptors ready for read
        grep(defined $_->{fd} && vec($fdvec, $_->{fd}, 1), @listen_sockets);
      if (!@ready_fd) {
        die "no file descriptors matching a bit field " . unpack('b*',$fdvec);
      } elsif (@ready_fd == 1) {  # easy, just one is ready
        $selected_socket_info = $ready_fd[0];
      } else {  # give equal opportunity to each ready socket
        my $j = int rand(@ready_fd);
        $selected_socket_info = $ready_fd[$j];
        dbg("spamd: requests ready on multiple sockets, picking #%d out of %d",
            $j+1, scalar @ready_fd);
      }

    } # end multiple sockets case

    if ($selected_socket_info) {
      my $socket = $selected_socket_info->{socket};
      $socket or die "no socket???, impossible";
      dbg("spamd: accept() on fd %d", $selected_socket_info->{fd});
      $client = $socket->accept;
      if (!defined $client) {
        if (defined $socket) {
          die sprintf("%s accept failed: %s\n", ref $socket,
                       $socket->isa('IO::Socket::SSL') ?
                         $socket->errstr : $@);
        } else {
          die "accept failed: no socket available: $!\n";
        }
      }
    }
    1;  # end eval with success

  } or do {
    my $err = $@ ne '' ? $@ : "errno=$!";  chomp $err;
    info("spamd: accept_a_conn: $err");
  };

  if ($locked) {
    dbg("spamd: releasing a lock over select+accept");
    flock($sockets_access_lock_fh, LOCK_UN)
      or die "Can't release sockets-access lock: $!";
  }

  return ($client, $selected_socket_info);
}

sub accept_a_conn {
  my ($timeout) = @_;

  my $socket_info;
  # $client is a global variable
  ($client, $socket_info) = accept_from_any_server_socket($timeout);

  if ($scaling) {
    $scaling->update_child_status_busy();
  }

  # Bah!
  if ( !$client  || !defined $client->connected() ) {

    # this can happen when interrupted by SIGCHLD on Solaris,
    # perl 5.8.0, and some other platforms with -m.
    if ( $! == &Errno::EINTR ) {
      return 0;
    }
    elsif ( $@ =~ /ssl3_get_record:wrong version number/ ||
            $@ =~ /peer did not return a certificate/ ) {
      # Handshake error, not speaking SSL? No need to respawn
      return 0;
    }
    else {
      return -1;
    }
  }

  $client->autoflush(1);

  # keep track of start time
  $spamtest->timer_reset;
  my $start = time;

  my ($remote_hostname, $remote_hostaddr, $local_port);

  if ($client->isa('IO::Socket::UNIX')) {
    $remote_hostname = 'localhost';
    $remote_hostaddr = '127.0.0.1';
    $remote_port = $socket_info->{path};
    info("spamd: got connection over %s", $socket_info->{path});
  }
  else {
    ($remote_port, $remote_hostaddr, $remote_hostname, $local_port) =
      peer_info_from_socket($client);
    $remote_hostaddr or die 'failed to obtain port and ip from socket';

    my $ssl_info = '';
    if ($client->isa('IO::Socket::SSL')) {
      $ssl_info = ', ';
      my $ssl_version = $client->get_sslversion();
      if (defined $ssl_version) {
        $ssl_info .= $ssl_version.'/';
      } else {
        $ssl_version = $client->get_sslversion_int();
        if    ($ssl_version == 0x0304) { $ssl_info .= 'TLSv1.3/'; }
        elsif ($ssl_version == 0x0303) { $ssl_info .= 'TLSv1.2/'; }
        elsif ($ssl_version == 0x0302) { $ssl_info .= 'TLSv1.1/'; }
        elsif ($ssl_version == 0x0301) { $ssl_info .= 'TLSv1.0/'; }
        elsif ($ssl_version == 0x0300) { $ssl_info .= 'SSLv3/'; }
        elsif ($ssl_version == 0x0002) { $ssl_info .= 'SSLv2/'; }
      }
      $ssl_info .= $client->get_cipher();
    }

    my $msg = sprintf("connection from %s [%s]:%s to port %d, fd %d%s",
                      $remote_hostname, $remote_hostaddr, $remote_port,
                      $local_port, $socket_info->{fd}, $ssl_info);

spamd/spamd.raw  view on Meta::CPAN

B<-A 10.11.12.13,10.11.12.14> -- only allow connections from C<10.11.12.13> and
C<10.11.12.14>.

B<-A 10.200.300.0/24> -- allow connections from any machine in the range
C<10.200.300.*>.

B<-A 10.> -- allow connections from any machine in the range C<10.*.*.*>.

B<-A [2001:db8::]/32,192.0.2.0/24,::1,127.0.0.0/8> -- only accept
connections from specified test networks and from localhost.

In absence of the B<-A> option, connections are only accepted from
IP address 127.0.0.1 or ::1, i.e. from localhost on a loopback interface.

=item B<-D> [I<area,...>], B<--debug> [I<area,...>]

Produce debugging output. If no areas are listed, all debugging information is
printed. Diagnostic output can also be enabled for each area individually;
I<area> is the area of the code to instrument. For example, to produce
diagnostic output on bayes, learn, and dns, use:

        spamassassin -D bayes,learn,dns

Higher priority informational messages that are suitable for logging in normal
circumstances are available with an area of "info".

For more information about which areas (also known as channels) are available,
please see the documentation at:

	C<https://wiki.apache.org/spamassassin/DebugChannels>

=item B<-4>, B<--ipv4only>, B<--ipv4-only>, B<--ipv4>

Use IPv4 where applicable, do not use IPv6.
The option affects a set of listen sockets (see option C<--listen>)
and disables IPv6 for DNS tests.

=item B<-6>

Use IPv6 where applicable, do not use IPv4.
The option affects a set of listen sockets (see option C<--listen>)
and disables IPv4 for DNS tests. Installing a module IO::Socket::IP
is recommended if spamd is expected to receive requests over IPv6.

=item B<-L>, B<--local>

Perform only local tests on all mail.  In other words, skip DNS and other
network tests.  Works the same as the C<-L> flag to C<spamassassin(1)>.

=item B<-P>, B<--paranoid>

Die on user errors (for the user passed from spamc) instead of falling back
to user C<--default-user> and using the default configuration.

=item B<-m> I<number> , B<--max-children>=I<number>

This option specifies the maximum number of children to spawn.
Spamd will spawn that number of children, then sleep in the background
until a child dies, wherein it will go and spawn a new child.

Incoming connections can still occur if all of the children are busy,
however those connections will be queued waiting for a free child.
The minimum value is C<1>, the default value is C<5>.

Please note that there is a OS specific maximum of connections that can be
queued (Try C<perl -MSocket -e'print SOMAXCONN'> to find this maximum).

Note that if you run too many servers for the amount of free RAM available, you
run the danger of hurting performance by causing a high swap load as server
processes are swapped in and out continually.

=item B<--min-children>=I<number>

The minimum number of children that will be kept running.  The minimum value is
C<1>, the default value is C<1>.  If you have lots of free RAM, you may want to
increase this.

=item B<--min-spare>=I<number>

The lower limit for the number of spare children allowed to run.  A
spare, or idle, child is one that is not handling a scan request.   If
there are too few spare children available, a new server will be started
every second or so.  The default value is C<1>.

=item B<--max-spare>=I<number>

The upper limit for the number of spare children allowed to run.  If there
are too many spare children, one will be killed every second or so until
the number of idle children is in the desired range.  The default value
is C<2>.

=item B<--max-conn-per-child>=I<number>

This option specifies the maximum number of connections each child
should process before dying and letting the master spamd process spawn
a new child.  The minimum value is C<1>, the default value is C<200>.

=item B<--round-robin>

By default, C<spamd> will attempt to keep a small number of "hot" child
processes as busy as possible, and keep any others as idle as possible, using
something similar to the Apache httpd server scaling algorithm.  This is
accomplished by the master process coordinating the activities of the children.
This switch will disable this scaling algorithm, and the behaviour seen in
the 3.0.x versions will be used instead, where all processes receive an
equal load and no scaling takes place.

=item B<--timeout-tcp>=I<number>

This option specifies the number of seconds to wait for headers from a
client (spamc) before closing the connection.  The minimum value is C<1>, 
the default value is C<30>, and a value of C<0> will disable socket
timeouts completely.

=item B<--timeout-child>=I<number>

This option specifies the number of seconds to wait for a spamd child to
process or check a message.  The minimum value is C<1>, the default 
value is C<300>, and a value of C<0> will disable child timeouts completely.

=item B<-H> I<directory>, B<--helper-home-dir>=I<directory>

Specify that external programs such as Razor, DCC, and Pyzor should have
a HOME environment variable set to a specific directory.  The default
is to use the HOME environment variable setting from the shell running
spamd.  By specifying no argument, spamd will use the spamc caller's
home directory instead.

=item B<--ssl>

Accept only SSL connections on the associated port.
The B<IO::Socket::SSL> perl module must be installed.

If the B<--ssl> switch is used, and B<--ssl-port> is not supplied, then
B<--port> port will be used to accept SSL connections instead of unencrypted
connections.  If the B<--ssl> switch is used, and B<--ssl-port> is set, then
unencrypted connections will be accepted on the B<--port>, at the same time as
encrypted connections are accepted at B<--ssl-port>.

=item B<--ssl-verify>

Implies B<--ssl>.  Request a client certificate and verify the certificate. 
Requires B<--ssl-ca-file> or B<--ssl-ca-path>.

=item B<--ssl-ca-file>=I<cafile>

Implies B<--ssl-verify>.  Use the specified Certificate Authority
certificate to verify the client certificate.  The client certificate must
be signed by this certificate.

=item B<--ssl-ca-path>=I<capath>

Implies B<--ssl-verify>.  Use the Certificate Authority certificate files in
the specified set of directories to verify the client certificate.  The
client certificate must be signed by one of these Certificate Authorities. 
See the man page for B<IO::Socket::SSL> for additional details.

=item B<--ssl-port>=I<port>

Optionally specifies the port number for the server to listen on for
SSL connections (default: whatever --port uses).  See B<--ssl> for



( run in 2.471 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )