---- Changes since 1.430 ----
When a virtual host's base directory is changed, all <directory> blocks under it are updated too.
When stopping and re-starting Apache, give it time to fully stop before continuing.
+---- Changes since 1.450 ----
+Fixed handling of IPv6 addresses so that Apache's [address] format is now fully supported.
: $n);
}
else {
- return &html_escape($_[0]->{'value'});
+ return &html_escape(
+ $_[0]->{'value'} =~ /^\[(\S+)\]$/ ? $1 :
+ $_[0]->{'value'} =~ /^\[(\S+)\]:(\d+)$/ ? "$1:$2" :
+ $_[0]->{'value'});
}
}
else { return $_[1] ? "*" : $text{'default_serv'}; }
}
}
-sub check_apache_ip6address
-{
-local ($ip) = @_;
-return $ip =~ /^\[(\S+)\]$/ && &check_ip6address("$1");
-}
-
1;
if (@$lref) {
# listen directives in use.. so BindAddress and Port are unused
foreach $l (@$lref) {
- if ($l->{'value'} =~ /^(\S+):(\d+)$/) {
+ if ($l->{'value'} =~ /^\[(\S+)\]:(\d+)$/) {
+ # IPv6 address and port
+ push(@blist, $1); push(@plist, $2);
+ }
+ elsif ($l->{'value'} =~ /^\[(\S+)\]$/) {
+ # IPv6 address only
+ push(@blist, $1); push(@plist, undef);
+ }
+ elsif ($l->{'value'} =~ /^(\S+):(\d+)$/) {
+ # IPv4 address and port
push(@blist, $1); push(@plist, $2);
}
elsif ($l->{'value'} =~ /^(\d+)$/) {
+ # Port only
push(@blist, "*"); push(@plist, $1);
}
elsif ($l->{'value'} =~ /^(\S+)$/) {
+ # IPv4 address or hostname only
push(@blist, $1); push(@plist, undef);
}
}
if ($bdef == 2) { next; }
if ($bdef) { push(@blist, "*"); }
- elsif ($b =~ /^\S+$/ && gethostbyname($b)) { push(@blist, $b); }
+ elsif ($b =~ /^\S+$/ &&
+ (gethostbyname($b) || &check_ipaddress($b) ||
+ &check_ip6address($b))) { push(@blist, $b); }
else { &error(&text('core_eaddress', $b)); }
if ($pdef) { push(@plist, undef); }
else {
# Apache 2.0 just uses Listen directives
for($i=0; $i<@blist; $i++) {
+ if (&check_ip6address($blist[$i])) {
+ $blist[$i] = "[".$blist[$i]."]";
+ }
if ($blist[$i] ne "*" && $plist[$i]) {
push(@l, "$blist[$i]:$plist[$i]");
}
local(@nv, $nv, $star);
foreach $nv (@{$_[0]}) {
if ($nv->{'value'} eq "*" && $_[1]->{'version'} >= 1.312) { $star++; }
+ elsif ($nv->{'value'} =~ /^\[(\S+)\]$/) { push(@nv, $1); }
else { push(@nv, $nv->{'value'}); }
}
if ($_[1]->{'version'} >= 1.312) {
foreach $nv (@nv) {
if ($nv =~ /^(\S+):(\d+|\*)$/) { $addr = $1; }
else { $addr = $nv; }
- if (!gethostbyname($addr) && $addr ne '*') {
+ if (!gethostbyname($addr) && !&check_ipaddress($addr) &&
+ !&check_ip6address($addr) && $addr ne '*') {
&error(&text('core_evirtaddr', $addr));
}
+ if ($nv =~ /^(\S+):(\d+|\*)$/ && &check_ip6address($1)) {
+ $nv = "[$1]:$2";
+ }
+ elsif (&check_ip6address($nv)) {
+ $nv = "[$nv]";
+ }
}
if (@nv) { return ( \@nv ); }
else { return ( [ ] ); }
&error($text{'cvirt_eaddr1'});
}
else {
- @addrs = split(/\s+/, $in{'addr'});
- foreach $a (@addrs) {
+ foreach $a (split(/\s+/, $in{'addr'})) {
gethostbyname($a) || &check_ipaddress($a) ||
- &check_apache_ip6address($a) ||
+ &check_ip6address($a) ||
&error(&text('cvirt_eaddr2', $a));
+ push(@addrs, &check_ip6address($a) ? "[$a]" : $a);
}
- $addr = $in{'addr'};
+ $addr = join(" ", @addrs);
}
# Parse and find the specified port
}
foreach $v (@virt) {
$vm = $v->{'members'};
- if ($v->{'words'}->[0] =~ /^(\S+):(\S+)$/) {
+ if ($v->{'words'}->[0] =~ /^\[(\S+)\]:(\d+)$/) {
+ # IPv6 address and port
+ $addr = $1;
+ $port = $2;
+ }
+ elsif ($v->{'words'}->[0] =~ /^(\S+):(\d+)$/) {
+ # IPv4 address and port
$addr = $1;
$port = $2;
}
else {
+ # Address, perhaps v6, with default port
$addr = $v->{'words'}->[0];
+ $addr = $1 if ($addr =~ /^\[(\S+)\]$/);
if ($httpd_modules{'core'} < 2.0) {
$port = &def(&find_directive("Port", $conf), 80);
}
[ [ 1, "$text{'index_any1'}<br>" ],
[ 2, "$text{'index_any2'}<br>" ],
[ 0, $text{'index_any0'}." ".
- &ui_textbox("addr", undef, 20) ] ])."<br>\n".
+ &ui_textbox("addr", undef, 40) ] ])."<br>\n".
&ui_checkbox("nv", 1, $text{'index_nv'}, 1)."<br>".
&ui_checkbox("listen", 1, $text{'index_listen'}, 1));
$_[0]->{'words'}->[0];
return $addr eq '_default_' || $addr eq '*' ? undef :
&check_ipaddress($addr) ? $addr :
- &check_apache_ip6address($addr) ? $addr :
+ $addr =~ /^\[(\S+)\]$/ && &check_ip6address($1) ? $1 :
&to_ipaddress($addr);
}
# Check address
if (defined($in{'addrs'})) {
+ # Multiple addresses
local @addrs = split(/\s+/, $in{'addrs'});
@addrs || &error($text{'vserv_eaddrs'});
foreach $a (@addrs) {
$addr = join(" ", @addrs);
}
else {
+ # One address
if ($in{'addr_def'} == 1) {
if ($httpd_modules{'core'} >= 1.2)
{ $addr = "_default_"; }
elsif ($in{'addr'} !~ /\S/) {
&error($text{'vserv_eaddr1'});
}
- elsif (!gethostbyname($in{'addr'})) {
+ elsif (!gethostbyname($in{'addr'}) &&
+ !&check_ipaddress($in{'addr'}) &&
+ !&check_ip6address($in{'addr'})) {
&error(&text('vserv_eaddr2', $in{'addr'}));
}
+ elsif (&check_ip6address($in{'addr'})) {
+ # IPv6 address
+ $addr = "[$in{'addr'}]";
+ }
else {
+ # IPv4 address or hostname
$addr = $in{'addr'};
}
}
if ($val =~ /\s/) {
$addrs = $val;
}
- if ($val =~ /^(\S+):(\S+)$/) {
+ if ($val =~ /^\[(\S+)\]:(\d+)$/) {
+ # IPv6 address and port
$addr = $1; $port = $2;
}
- else { $addr = $val; }
+ elsif ($val =~ /^\[(\S+)\]$/) {
+ # IPv6 address
+ $addr = $1;
+ }
+ elsif ($val =~ /^(\S+):(\d+)$/) {
+ # IPv4 address or hostname and port
+ $addr = $1; $port = $2;
+ }
+ else {
+ # IPv4 address or hostname
+ $addr = $val;
+ }
if ($addrs) {
# Multiple addresses and ports
[ 2, $text{'vserv_any'} ],
[ 0, &ui_textbox("addr",
$addr eq "*" || $addr eq "_default_" ?
- "" : $addr, 20) ] ]));
+ "" : $addr, 40) ] ]));
print &ui_table_row($text{'vserv_port'},
&choice_input($port eq "*" ? 1 : $port > 0 ? 2 : 0,