diff --git a/qpsmtpd-forkserver b/qpsmtpd-forkserver index 4bedb51..5971e52 100755 --- a/qpsmtpd-forkserver +++ b/qpsmtpd-forkserver @@ -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 {