From 6ed494275b8f84468a1dc7f6ab552e4a2e0d70b9 Mon Sep 17 00:00:00 2001 From: Matt Sergeant Date: Sat, 18 Jun 2005 18:20:49 +0000 Subject: [PATCH] Support a flag for how many connections to accept in the accept loop git-svn-id: https://svn.perl.org/qpsmtpd/branches/high_perf@435 958fd67b-6ff1-0310-b445-bb7760255be9 --- qpsmtpd | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/qpsmtpd b/qpsmtpd index f7076b5..42fb28e 100755 --- a/qpsmtpd +++ b/qpsmtpd @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl use lib "./lib"; BEGIN { @@ -44,6 +44,7 @@ my $MAXCONN = 15; # max simultaneous connections my $USER = 'smtpd'; # user to suid to my $MAXCONNIP = 5; # max simultaneous connections from one IP my $PAUSED = 0; +my $NUMACCEPT = 20; sub help { print < \$MAXCONN, 'm|max-from-ip=i' => \$MAXCONNIP, 'u|user=s' => \$USER, + 'a|accept=i' => \$NUMACCEPT, 'h|help' => \&help, ) || help(); @@ -86,6 +89,7 @@ if ($LOCALADDR =~ /^([\d\w\-.]+)$/) { $LOCALADDR = $1 } else { &help } if ($USER =~ /^([\w\-]+)$/) { $USER = $1 } else { &help } if ($MAXCONN =~ /^(\d+)$/) { $MAXCONN = $1 } else { &help } if ($PROCS =~ /^(\d+)$/) { $PROCS = $1 } else { &help } +if ($NUMACCEPT =~ /^(\d+)$/) { $NUMACCEPT = $1 } else { &help } $PROCS = 1 if $LineMode; # This is a bit of a hack, but we get to approximate MAXCONN stuff when we @@ -300,9 +304,7 @@ sub accept_handler { $running = scalar keys %$descriptors; } - my $max = $MAXCONNIP ? 100 : 1000; - - for (1 .. $max) { + for (1 .. $NUMACCEPT) { if ($running >= $MAXCONN) { ::log(LOGINFO,"Too many connections: $running >= $MAXCONN."); return; @@ -312,13 +314,22 @@ sub accept_handler { } } +use Errno qw(EAGAIN EWOULDBLOCK); + sub _accept_handler { my $running = shift; - + my $csock = $SERVER->accept(); if (!$csock) { # warn("accept() failed: $!"); return; + if ($! == EAGAIN || $! == EWOULDBLOCK) { + return; + } + else { + warn("accept() failed: $!"); + return 1; + } } binmode($csock, ':raw'); @@ -331,6 +342,7 @@ sub _accept_handler { if (!$LineMode) { # multiplex mode my $client = Qpsmtpd::PollServer->new($csock); + my $rem_ip = $client->peer_ip_string; if ($PAUSED) { $client->write("451 Sorry, this server is currently paused\r\n"); @@ -340,8 +352,7 @@ sub _accept_handler { if ($MAXCONNIP) { my $num_conn = 1; # seed with current value - my $rem_ip = $client->peer_ip_string; - + # If we for-loop directly over values %childstatus, a SIGCHLD # can call REAPER and slip $rip out from under us. Causes # "Use of freed value in iteration" under perl 5.8.4. @@ -426,7 +437,7 @@ sub _accept_handler { sub log { my ($level,$message) = @_; # $level not used yet. this is reimplemented from elsewhere anyway - warn("$$ $message\n"); + warn("$$ fd:? $message\n"); } sub pause {