Implement listening on multiple local addresses simultaneously, if specified by
more than one --listen-address commandline argument. git-svn-id: https://svn.perl.org/qpsmtpd/trunk@464 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
parent
314625d05a
commit
1fbfe5156b
3
Changes
3
Changes
@ -1,5 +1,8 @@
|
|||||||
0.31 -
|
0.31 -
|
||||||
|
|
||||||
|
qpsmtpd-forkserver: --listen-address may now be given more than once, to
|
||||||
|
request listening on multiple local addresses (Devin Carraway)
|
||||||
|
|
||||||
qpsmtpd-forkserver: add an option for writing a PID file (pjh)
|
qpsmtpd-forkserver: add an option for writing a PID file (pjh)
|
||||||
|
|
||||||
qpsmtpd-forkserver: set auxiliary groups (this is needed for the
|
qpsmtpd-forkserver: set auxiliary groups (this is needed for the
|
||||||
|
@ -20,7 +20,7 @@ $| = 1;
|
|||||||
# Configuration
|
# Configuration
|
||||||
my $MAXCONN = 15; # max simultaneous connections
|
my $MAXCONN = 15; # max simultaneous connections
|
||||||
my $PORT = 2525; # port number
|
my $PORT = 2525; # port number
|
||||||
my $LOCALADDR = '0.0.0.0'; # ip address to bind to
|
my @LOCALADDR; # ip address to bind to
|
||||||
my $USER = 'smtpd'; # user to suid to
|
my $USER = 'smtpd'; # user to suid to
|
||||||
my $MAXCONNIP = 5; # max simultaneous connections from one IP
|
my $MAXCONNIP = 5; # max simultaneous connections from one IP
|
||||||
my $PID_FILE = '';
|
my $PID_FILE = '';
|
||||||
@ -28,7 +28,9 @@ my $PID_FILE = '';
|
|||||||
sub usage {
|
sub usage {
|
||||||
print <<"EOT";
|
print <<"EOT";
|
||||||
usage: qpsmtpd-forkserver [ options ]
|
usage: qpsmtpd-forkserver [ options ]
|
||||||
-l, --listen-address addr : listen on a specific address; default 0.0.0.0
|
-l, --listen-address addr : listen on specific address(es); can be specified
|
||||||
|
multiple times for multiple bindings. Default is
|
||||||
|
0.0.0.0 (all interfaces).
|
||||||
-p, --port P : listen on a specific port; default 2525
|
-p, --port P : listen on a specific port; default 2525
|
||||||
-c, --limit-connections N : limit concurrent connections to N; default 15
|
-c, --limit-connections N : limit concurrent connections to N; default 15
|
||||||
-u, --user U : run as a particular user (default 'smtpd')
|
-u, --user U : run as a particular user (default 'smtpd')
|
||||||
@ -39,7 +41,7 @@ EOT
|
|||||||
}
|
}
|
||||||
|
|
||||||
GetOptions('h|help' => \&usage,
|
GetOptions('h|help' => \&usage,
|
||||||
'l|listen-address=s' => \$LOCALADDR,
|
'l|listen-address=s' => \@LOCALADDR,
|
||||||
'c|limit-connections=i' => \$MAXCONN,
|
'c|limit-connections=i' => \$MAXCONN,
|
||||||
'm|max-from-ip=i' => \$MAXCONNIP,
|
'm|max-from-ip=i' => \$MAXCONNIP,
|
||||||
'p|port=i' => \$PORT,
|
'p|port=i' => \$PORT,
|
||||||
@ -49,7 +51,14 @@ GetOptions('h|help' => \&usage,
|
|||||||
|
|
||||||
# detaint the commandline
|
# detaint the commandline
|
||||||
if ($PORT =~ /^(\d+)$/) { $PORT = $1 } else { &usage }
|
if ($PORT =~ /^(\d+)$/) { $PORT = $1 } else { &usage }
|
||||||
if ($LOCALADDR =~ /^([\d\w\-.]+)$/) { $LOCALADDR = $1 } else { &usage }
|
@LOCALADDR = ( '0.0.0.0' ) if !@LOCALADDR;
|
||||||
|
for (0..$#LOCALADDR) {
|
||||||
|
if ($LOCALADDR[$_] =~ /^([\d\w\-.]+)$/) {
|
||||||
|
$LOCALADDR[$_] = $1;
|
||||||
|
} else {
|
||||||
|
&usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
if ($USER =~ /^([\w\-]+)$/) { $USER = $1 } else { &usage }
|
if ($USER =~ /^([\w\-]+)$/) { $USER = $1 } else { &usage }
|
||||||
if ($MAXCONN =~ /^(\d+)$/) { $MAXCONN = $1 } else { &usage }
|
if ($MAXCONN =~ /^(\d+)$/) { $MAXCONN = $1 } else { &usage }
|
||||||
|
|
||||||
@ -75,17 +84,20 @@ sub HUNTSMAN {
|
|||||||
$SIG{INT} = \&HUNTSMAN;
|
$SIG{INT} = \&HUNTSMAN;
|
||||||
$SIG{TERM} = \&HUNTSMAN;
|
$SIG{TERM} = \&HUNTSMAN;
|
||||||
|
|
||||||
# establish SERVER socket, bind and listen.
|
my $select = new IO::Select;
|
||||||
my $server = IO::Socket::INET->new(LocalPort => $PORT,
|
|
||||||
LocalAddr => $LOCALADDR,
|
# establish SERVER socket(s), bind and listen.
|
||||||
|
for my $listen_addr (@LOCALADDR) {
|
||||||
|
my $server = IO::Socket::INET->new(LocalPort => $PORT,
|
||||||
|
LocalAddr => $listen_addr,
|
||||||
Proto => 'tcp',
|
Proto => 'tcp',
|
||||||
Reuse => 1,
|
Reuse => 1,
|
||||||
Blocking => 0,
|
Blocking => 0,
|
||||||
Listen => SOMAXCONN )
|
Listen => SOMAXCONN )
|
||||||
or die "Creating TCP socket $LOCALADDR:$PORT: $!\n";
|
or die "Creating TCP socket $listen_addr:$PORT: $!\n";
|
||||||
IO::Handle::blocking($server, 0);
|
IO::Handle::blocking($server, 0);
|
||||||
my $sel = IO::Select->new();
|
$select->add($server);
|
||||||
$sel->add($server);
|
}
|
||||||
|
|
||||||
if ($PID_FILE) {
|
if ($PID_FILE) {
|
||||||
if ($PID_FILE =~ m#^(/[\w\d/\-.]+)$#) { $PID_FILE = $1 } else { &usage }
|
if ($PID_FILE =~ m#^(/[\w\d/\-.]+)$#) { $PID_FILE = $1 } else { &usage }
|
||||||
@ -145,8 +157,12 @@ while (1) {
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
next unless $sel->can_read(1);
|
my @ready = $select->can_read(1);
|
||||||
my $hisaddr = accept(my $client, $server);
|
next if !@ready;
|
||||||
|
my $server = shift @ready;
|
||||||
|
|
||||||
|
my ($client, $hisaddr) = $server->accept;
|
||||||
|
|
||||||
if (!$hisaddr) {
|
if (!$hisaddr) {
|
||||||
# possible something condition...
|
# possible something condition...
|
||||||
next;
|
next;
|
||||||
|
Loading…
Reference in New Issue
Block a user