On Mon, 2004-03-29 at 16:21 -0800, Stas Bekman wrote:
> Philippe M. Chiasson wrote:
> > On Mon, 2004-03-29 at 15:43 -0800, Stas Bekman wrote:
> >
> >>Philippe M. Chiasson wrote:
> >>
> >>>After a bit of poking around different flavors of IPv6 systems, I've
> >>>encountered a few situations where Apache::Test ends up configuring
> >>>httpd in a way that can't be tested.
> >>>
> >>>This typically only happens on a system that has IPv4-mapped IPv6
> >>>addresses disabled, i.e. OpenBSD. If the hostname that is picked
> >>>to form the Listen directives happens to have both an IPv4 and an
> >>>IPv6 address, i.e localhot on OpenBSD, the server will start but will
> >>>only be listening on an IPv6 address.
> >>>
> >>>And since LWP doesn't do requests over IPv6, all tests will fail.
> >>>
> >>>The following patch attempts to do handle all this by doing one of a few
> >>>many things.
> >>
> >>gozer++
> >>
> >>
> >>>If the server has ipv4-mapped addresses, Listen to *:port, forcing the
> >>>use of ipv4-mapped addresses and insuring that the server will be
> >>>available over it's ipv4 address.
> >>>
> >>>Otherwise try to use Socket6 to see if the hostname is both v4 and v6
> >>>and Listen to *:port as well. Without Socket6 (not part of the Perl
> >>>core), just warn the user about possible problems he/she will run into
> >>>if the selected hostname happens to be ipv6.
> >>
> >>[...]
> >>
> >>>+ else {
> >>>+ if (eval { require Socket6 }) {
> >>>+ if (Socket6::gethostbyname2($name, Socket6::AF_INET6())) {
> >>>+ $self->{vars}{listen_addr} = '*';
> >>>+ }
> >>>+ }
> >>>+ else {
> >>>+ warning "Socket6 not installed";
> >>>+ warning "Test might fail if your hostname: '$name' has an
> >>>IPv6 address";
> >>
> >>I think we should die here:
> >>
> >> error << EOI;
> >>Your system is configured to run both ipv6 and ipv4, but the right
> >>interface
> >>can't be selected.
> >>Please install the perl CPAN module Socket6 and re-run the last command.
> >>EOI
> >> die "\n";
> >
> >
> > That's something I considered, but I figured it was better to be gentle
> > and just warn people that things might not work. I am perfectly fine
> > with die instead.
> >
> >
> >>and if Socket6 builds everywhere, and including older perls, we should
> >>include
> >>it in Apache-Test's %PREREQ_PM.
> >
> >
> > Well, I built it successfully with a combination of 5.8.x and 5.6.x on
> > linux, freebsd and openbsd. I am not sure if it builds on systems
> > without ipv4 support though.
>
> OK, so let's keep it warning/out of prereq for now while we polish it.
Sure!
> but please replace s/warning/error/ so it'll more prominent. thanks.
Patch following:
Index: Apache-Test/lib/Apache/TestConfig.pm
===================================================================
RCS file:
/home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestConfig.pm,v
retrieving revision 1.213
diff -u -I$Id -r1.213 TestConfig.pm
--- Apache-Test/lib/Apache/TestConfig.pm 4 Mar 2004 05:51:31 -0000
1.213
+++ Apache-Test/lib/Apache/TestConfig.pm 30 Mar 2004 00:48:58 -0000
@@ -63,6 +63,7 @@
documentroot => 'DocumentRoot (default is $ServerRoot/htdocs',
port => 'Port [port_number|select] (default ' . DEFAULT_PORT .
')',
servername => 'ServerName (default is localhost)',
+ listen_addr => 'The address to use in Listen directives',
user => 'User to run test server as (default is $USER)',
group => 'Group to run test server as (default is $GROUP)',
bindir => 'Apache bin/ dir (default is apxs -q BINDIR)',
@@ -272,7 +273,7 @@
$vars->{servername} ||= $self->default_servername;
$vars->{port} = $self->select_first_port;
$vars->{remote_addr} ||= $self->our_remote_addr;
-
+ $vars->{listen_addr} ||= $self->default_localhost;
$vars->{user} ||= $self->default_user;
$vars->{group} ||= $self->default_group;
$vars->{serveradmin} ||= $self->default_serveradmin;
@@ -286,6 +287,8 @@
$self->inherit_config; #see TestConfigParse.pm
$self->configure_httpd_eapi; #must come after inherit_config
+ $self->check_ipv6;
+
$self->default_module(cgi => [qw(mod_cgi mod_cgid)]);
$self->default_module(thread => [qw(worker threaded)]);
$self->default_module(ssl => [qw(mod_ssl)]);
@@ -637,6 +640,45 @@
$remote_addr ||= Socket::inet_ntoa($iaddr);
}
+my $apr_ipv6;
+sub apr_has_ipv6 {
+ my $self = shift;
+ return $apr_ipv6 if defined $apr_ipv6;
+ foreach my $key (keys %{$self->{httpd_defines}}) {
+ return $apr_ipv6 = $key if $key =~ /^APR_HAVE_IPV6/;
+ }
+}
+
+sub apr_has_ipv4_mapped {
+ my $self = shift;
+ return $self->apr_has_ipv6 =~ /IPv4-mapped addresses enabled/;
+}
+
+sub check_ipv6 {
+ my $self = shift;
+
+ return if $self->{vars}{listen_addr} ne $self->default_localhost;
+
+ my $name = $self->{vars}{servername};
+
+ if ($self->apr_has_ipv6) {
+ if ($self->apr_has_ipv4_mapped) {
+ $self->{vars}{listen_addr} = '*';
+ }
+ else {
+ if (eval { require Socket6 }) {
+ if (Socket6::gethostbyname2($name, Socket6::AF_INET6())) {
+ $self->{vars}{listen_addr} = '*';
+ }
+ }
+ else {
+ error "Socket6 not installed";
+ error "Test might fail if your hostname: '$name' has an IPv6
address";
+ }
+ }
+ }
+}
+
sub default_loopback {
'127.0.0.1';
}
@@ -1017,7 +1059,7 @@
my @out_config = ();
if ($self->{vhosts}->{$module}->{namebased} < 2) {
#extra config that should go *outside* the <VirtualHost ...>
- @out_config = ([Listen => $vars->{servername} . ':' . $port]);
+ @out_config = ([Listen => $vars->{listen_addr} . ':' . $port]);
if ($self->{vhosts}->{$module}->{namebased}) {
push @out_config => [NameVirtualHost => "*:$port"];
@@ -1785,7 +1827,7 @@
__DATA__
-Listen @ServerName@:@Port@
+Listen @Listen_Addr@:@Port@
ServerRoot "@ServerRoot@"
DocumentRoot "@DocumentRoot@"
Index: Apache-Test/lib/Apache/TestConfigPerl.pm
===================================================================
RCS file:
/home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestConfigPerl.pm,v
retrieving revision 1.85
diff -u -I$Id -r1.85 TestConfigPerl.pm
--- Apache-Test/lib/Apache/TestConfigPerl.pm 16 Mar 2004 03:10:32 -0000
1.85
+++ Apache-Test/lib/Apache/TestConfigPerl.pm 30 Mar 2004 00:48:58 -0000
@@ -222,7 +222,7 @@
my($self, $module, $args) = @_;
my $port = $self->new_vhost($module);
my $vars = $self->{vars};
- $self->postamble(Listen => $vars->{servername} . ':' . $port);
+ $self->postamble(Listen => $vars->{listen_addr} . ':' . $port);
}
my %add_hook_config = (
> --
> __________________________________________________________________
> Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
> http://stason.org/ mod_perl Guide ---> http://perl.apache.org
> mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
> http://modperlbook.org http://apache.org http://ticketmaster.com
Index: Apache-Test/lib/Apache/TestConfig.pm
===================================================================
RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestConfig.pm,v
retrieving revision 1.213
diff -u -I$Id -r1.213 TestConfig.pm
--- Apache-Test/lib/Apache/TestConfig.pm 4 Mar 2004 05:51:31 -0000 1.213
+++ Apache-Test/lib/Apache/TestConfig.pm 30 Mar 2004 00:48:58 -0000
@@ -63,6 +63,7 @@
documentroot => 'DocumentRoot (default is $ServerRoot/htdocs',
port => 'Port [port_number|select] (default ' . DEFAULT_PORT . ')',
servername => 'ServerName (default is localhost)',
+ listen_addr => 'The address to use in Listen directives',
user => 'User to run test server as (default is $USER)',
group => 'Group to run test server as (default is $GROUP)',
bindir => 'Apache bin/ dir (default is apxs -q BINDIR)',
@@ -272,7 +273,7 @@
$vars->{servername} ||= $self->default_servername;
$vars->{port} = $self->select_first_port;
$vars->{remote_addr} ||= $self->our_remote_addr;
-
+ $vars->{listen_addr} ||= $self->default_localhost;
$vars->{user} ||= $self->default_user;
$vars->{group} ||= $self->default_group;
$vars->{serveradmin} ||= $self->default_serveradmin;
@@ -286,6 +287,8 @@
$self->inherit_config; #see TestConfigParse.pm
$self->configure_httpd_eapi; #must come after inherit_config
+ $self->check_ipv6;
+
$self->default_module(cgi => [qw(mod_cgi mod_cgid)]);
$self->default_module(thread => [qw(worker threaded)]);
$self->default_module(ssl => [qw(mod_ssl)]);
@@ -637,6 +640,45 @@
$remote_addr ||= Socket::inet_ntoa($iaddr);
}
+my $apr_ipv6;
+sub apr_has_ipv6 {
+ my $self = shift;
+ return $apr_ipv6 if defined $apr_ipv6;
+ foreach my $key (keys %{$self->{httpd_defines}}) {
+ return $apr_ipv6 = $key if $key =~ /^APR_HAVE_IPV6/;
+ }
+}
+
+sub apr_has_ipv4_mapped {
+ my $self = shift;
+ return $self->apr_has_ipv6 =~ /IPv4-mapped addresses enabled/;
+}
+
+sub check_ipv6 {
+ my $self = shift;
+
+ return if $self->{vars}{listen_addr} ne $self->default_localhost;
+
+ my $name = $self->{vars}{servername};
+
+ if ($self->apr_has_ipv6) {
+ if ($self->apr_has_ipv4_mapped) {
+ $self->{vars}{listen_addr} = '*';
+ }
+ else {
+ if (eval { require Socket6 }) {
+ if (Socket6::gethostbyname2($name, Socket6::AF_INET6())) {
+ $self->{vars}{listen_addr} = '*';
+ }
+ }
+ else {
+ error "Socket6 not installed";
+ error "Test might fail if your hostname: '$name' has an IPv6 address";
+ }
+ }
+ }
+}
+
sub default_loopback {
'127.0.0.1';
}
@@ -1017,7 +1059,7 @@
my @out_config = ();
if ($self->{vhosts}->{$module}->{namebased} < 2) {
#extra config that should go *outside* the <VirtualHost ...>
- @out_config = ([Listen => $vars->{servername} . ':' . $port]);
+ @out_config = ([Listen => $vars->{listen_addr} . ':' . $port]);
if ($self->{vhosts}->{$module}->{namebased}) {
push @out_config => [NameVirtualHost => "*:$port"];
@@ -1785,7 +1827,7 @@
__DATA__
-Listen @ServerName@:@Port@
+Listen @Listen_Addr@:@Port@
ServerRoot "@ServerRoot@"
DocumentRoot "@DocumentRoot@"
Index: Apache-Test/lib/Apache/TestConfigPerl.pm
===================================================================
RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestConfigPerl.pm,v
retrieving revision 1.85
diff -u -I$Id -r1.85 TestConfigPerl.pm
--- Apache-Test/lib/Apache/TestConfigPerl.pm 16 Mar 2004 03:10:32 -0000 1.85
+++ Apache-Test/lib/Apache/TestConfigPerl.pm 30 Mar 2004 00:48:58 -0000
@@ -222,7 +222,7 @@
my($self, $module, $args) = @_;
my $port = $self->new_vhost($module);
my $vars = $self->{vars};
- $self->postamble(Listen => $vars->{servername} . ':' . $port);
+ $self->postamble(Listen => $vars->{listen_addr} . ':' . $port);
}
my %add_hook_config = (
signature.asc
Description: This is a digitally signed message part
