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