Make sure we process all servers after select()
git-svn-id: https://svn.perl.org/qpsmtpd/trunk@466 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
parent
1e68345cf2
commit
3fc6a4f318
@ -159,81 +159,81 @@ while (1) {
|
||||
}
|
||||
my @ready = $select->can_read(1);
|
||||
next if !@ready;
|
||||
my $server = shift @ready;
|
||||
|
||||
my ($client, $hisaddr) = $server->accept;
|
||||
|
||||
if (!$hisaddr) {
|
||||
# possible something condition...
|
||||
next;
|
||||
}
|
||||
IO::Handle::blocking($client, 1);
|
||||
my ($port, $iaddr) = sockaddr_in($hisaddr);
|
||||
if ($MAXCONNIP) {
|
||||
my $num_conn = 1; # seed with current value
|
||||
|
||||
foreach my $rip (values %childstatus) {
|
||||
++$num_conn if (defined $rip && $rip eq $iaddr);
|
||||
}
|
||||
|
||||
if ($num_conn > $MAXCONNIP) {
|
||||
my $rem_ip = inet_ntoa($iaddr);
|
||||
::log(LOGINFO,"Too many connections from $rem_ip: "
|
||||
."$num_conn > $MAXCONNIP. Denying connection.");
|
||||
$client->autoflush(1);
|
||||
print $client "451 Sorry, too many connections from $rem_ip, try again later\r\n";
|
||||
close $client;
|
||||
while (my $server = shift @ready) {
|
||||
my ($client, $hisaddr) = $server->accept;
|
||||
|
||||
if (!$hisaddr) {
|
||||
# possible something condition...
|
||||
next;
|
||||
}
|
||||
IO::Handle::blocking($client, 1);
|
||||
my ($port, $iaddr) = sockaddr_in($hisaddr);
|
||||
if ($MAXCONNIP) {
|
||||
my $num_conn = 1; # seed with current value
|
||||
|
||||
foreach my $rip (values %childstatus) {
|
||||
++$num_conn if (defined $rip && $rip eq $iaddr);
|
||||
}
|
||||
|
||||
if ($num_conn > $MAXCONNIP) {
|
||||
my $rem_ip = inet_ntoa($iaddr);
|
||||
::log(LOGINFO,"Too many connections from $rem_ip: "
|
||||
."$num_conn > $MAXCONNIP. Denying connection.");
|
||||
$client->autoflush(1);
|
||||
print $client "451 Sorry, too many connections from $rem_ip, try again later\r\n";
|
||||
close $client;
|
||||
next;
|
||||
}
|
||||
}
|
||||
my $pid = safe_fork();
|
||||
if ($pid) {
|
||||
# parent
|
||||
$childstatus{$pid} = $iaddr; # add to table
|
||||
# $childstatus{$pid} = 1; # add to table
|
||||
$running++;
|
||||
close($client);
|
||||
next;
|
||||
}
|
||||
# otherwise child
|
||||
|
||||
# all children should have different seeds, to prevent conflicts
|
||||
srand( time ^ ($$ + ($$ << 15)) );
|
||||
|
||||
close($server);
|
||||
|
||||
$SIG{$_} = 'DEFAULT' for keys %SIG;
|
||||
$SIG{ALRM} = sub {
|
||||
print $client "421 Connection Timed Out\n";
|
||||
::log(LOGINFO, "Connection Timed Out");
|
||||
exit; };
|
||||
|
||||
my $localsockaddr = getsockname($client);
|
||||
my ($lport, $laddr) = sockaddr_in($localsockaddr);
|
||||
$ENV{TCPLOCALIP} = inet_ntoa($laddr);
|
||||
# my ($port, $iaddr) = sockaddr_in($hisaddr);
|
||||
$ENV{TCPREMOTEIP} = inet_ntoa($iaddr);
|
||||
$ENV{TCPREMOTEHOST} = gethostbyaddr($iaddr, AF_INET) || "Unknown";
|
||||
|
||||
# don't do this!
|
||||
#$0 = "qpsmtpd-forkserver: $ENV{TCPREMOTEIP} / $ENV{TCPREMOTEHOST}";
|
||||
|
||||
::log(LOGINFO, "Accepted connection $running/$MAXCONN from $ENV{TCPREMOTEIP} / $ENV{TCPREMOTEHOST}");
|
||||
|
||||
# dup to STDIN/STDOUT
|
||||
POSIX::dup2(fileno($client), 0);
|
||||
POSIX::dup2(fileno($client), 1);
|
||||
|
||||
$qpsmtpd->start_connection
|
||||
(
|
||||
local_ip => $ENV{TCPLOCALIP},
|
||||
local_port => $lport,
|
||||
remote_ip => $ENV{TCPREMOTEIP},
|
||||
remote_port => $port,
|
||||
);
|
||||
$qpsmtpd->run();
|
||||
|
||||
exit; # child leaves
|
||||
}
|
||||
my $pid = safe_fork();
|
||||
if ($pid) {
|
||||
# parent
|
||||
$childstatus{$pid} = $iaddr; # add to table
|
||||
# $childstatus{$pid} = 1; # add to table
|
||||
$running++;
|
||||
close($client);
|
||||
next;
|
||||
}
|
||||
# otherwise child
|
||||
|
||||
# all children should have different seeds, to prevent conflicts
|
||||
srand( time ^ ($$ + ($$ << 15)) );
|
||||
|
||||
close($server);
|
||||
|
||||
$SIG{$_} = 'DEFAULT' for keys %SIG;
|
||||
$SIG{ALRM} = sub {
|
||||
print $client "421 Connection Timed Out\n";
|
||||
::log(LOGINFO, "Connection Timed Out");
|
||||
exit; };
|
||||
|
||||
my $localsockaddr = getsockname($client);
|
||||
my ($lport, $laddr) = sockaddr_in($localsockaddr);
|
||||
$ENV{TCPLOCALIP} = inet_ntoa($laddr);
|
||||
# my ($port, $iaddr) = sockaddr_in($hisaddr);
|
||||
$ENV{TCPREMOTEIP} = inet_ntoa($iaddr);
|
||||
$ENV{TCPREMOTEHOST} = gethostbyaddr($iaddr, AF_INET) || "Unknown";
|
||||
|
||||
# don't do this!
|
||||
#$0 = "qpsmtpd-forkserver: $ENV{TCPREMOTEIP} / $ENV{TCPREMOTEHOST}";
|
||||
|
||||
::log(LOGINFO, "Accepted connection $running/$MAXCONN from $ENV{TCPREMOTEIP} / $ENV{TCPREMOTEHOST}");
|
||||
|
||||
# dup to STDIN/STDOUT
|
||||
POSIX::dup2(fileno($client), 0);
|
||||
POSIX::dup2(fileno($client), 1);
|
||||
|
||||
$qpsmtpd->start_connection
|
||||
(
|
||||
local_ip => $ENV{TCPLOCALIP},
|
||||
local_port => $lport,
|
||||
remote_ip => $ENV{TCPREMOTEIP},
|
||||
remote_port => $port,
|
||||
);
|
||||
$qpsmtpd->run();
|
||||
|
||||
exit; # child leaves
|
||||
}
|
||||
|
||||
sub log {
|
||||
|
Loading…
Reference in New Issue
Block a user