Cope better with IPv6 addresses

This commit is contained in:
duncan_ferguson 2009-04-06 19:40:13 +00:00
parent 2a56ac9247
commit ce1f23d41a
2 changed files with 119 additions and 43 deletions

View file

@ -5,6 +5,7 @@
* Continue connecting to unresolvable hosts (debian bug 499935) (Tony Mancill) * Continue connecting to unresolvable hosts (debian bug 499935) (Tony Mancill)
* Correct bug with unset default ports (Tony Mancill) * Correct bug with unset default ports (Tony Mancill)
* Rearrange pod documentation to remove extraenous comment (Tony Mancill) * Rearrange pod documentation to remove extraenous comment (Tony Mancill)
* Cope better with IPv6 addresses
2009-03-26 Duncan Ferguson <duncan_ferguson@user.sf.net> - v3.25-1 2009-03-26 Duncan Ferguson <duncan_ferguson@user.sf.net> - v3.25-1

View file

@ -80,6 +80,7 @@ use X11::Keysyms '%keysymtocode', 'MISCELLANY', 'XKB_KEYS', '3270', 'LATIN1',
'TECHNICAL', 'SPECIAL', 'PUBLISHING', 'APL', 'HEBREW', 'THAI', 'KOREAN'; 'TECHNICAL', 'SPECIAL', 'PUBLISHING', 'APL', 'HEBREW', 'THAI', 'KOREAN';
use File::Basename; use File::Basename;
use Net::hostent; use Net::hostent;
use Carp;
### all global variables ### ### all global variables ###
my $scriptname = $0; my $scriptname = $0;
@ -169,6 +170,10 @@ sub exit_prog() {
sub logmsg($@) { sub logmsg($@) {
my $level = shift; my $level = shift;
if ( $level > 3 ) {
croak('requested debug level should not be above 3');
}
if ( $level <= $debug ) { if ( $level <= $debug ) {
print( strftime( "%H:%M:%S: ", localtime ) ) if ( $debug > 1 ); print( strftime( "%H:%M:%S: ", localtime ) ) if ( $debug > 1 );
print @_, $/; print @_, $/;
@ -866,8 +871,54 @@ sub setup_helper_script() {
logmsg( 2, "Helper script done" ); logmsg( 2, "Helper script done" );
} }
sub split_hostname {
my ($server) = @_;
logmsg( 3, 'split_hostname: server=' . $server );
my $username = q{};
$username = $config{user} if ( $config{user} );
if ( $server =~ s/^(.*)@// ) {
$username = $1;
}
# try to cope with IPv6 addresses
# if $server contains '::' assume this is IPv6 address
# if there are 8 : in the address then can say its IPv6 + port
# otherwise how can you reliably tell its IPv6 + port when last
# octect is number, i.e. is 2001:db8::1428:2323 a host with
# port 2323 or a full IPv6 address?
my $port = q{};
if ( $server !~ m/::/ || ( $server =~ tr/:// ) == 7 ) {
if ( $server =~ s/:(\d+)$// ) {
$port = $1;
}
}
else {
if ( $server =~ m/:(\d+)$/ ) {
our $seen_error;
warn 'Potentially ambiguous IPv6 address/port definition: ',
$server, $/;
warn 'Assuming it is an IPv6 address only.', $/;
if(! $seen_error) {
warn '*** See documenation for more information.', $/;
$seen_error = 1;
}
}
}
logmsg( 3, "username=$username, server=$server, port=$port" );
return ( $username, $server, $port );
}
sub check_host($) { sub check_host($) {
my $host = shift; my $host = shift;
if ( $host =~ m/:/ ) {
logmsg( 2, "Not resolving IPv6 address '$host'" );
return 1;
}
if ( $host =~ m/^(\d{1,3}\.?){4}$/ ) { if ( $host =~ m/^(\d{1,3}\.?){4}$/ ) {
logmsg( 2, "Not resolving IP address '$host'" ); logmsg( 2, "Not resolving IP address '$host'" );
return 1; return 1;
@ -892,28 +943,10 @@ sub open_client_windows(@) {
foreach (@_) { foreach (@_) {
next unless ($_); next unless ($_);
my $username = ""; my ( $username, $server, $port_nb ) = split_hostname($_);
$username = $config{user} if ( $config{user} );
my $port_nb;
# split off any provided hostname and port
if ( $_ =~ s/^(.*)@// ) {
$username = $1;
}
if ( $_ =~ s/:(\w+)$// ) {
$port_nb = $1;
}
my $count = 1;
my $server = $_;
while ( defined( $servers{$server} ) ) {
$server = $_ . " " . $count++;
}
# see if we can find the hostname - if not, drop it # see if we can find the hostname - if not, drop it
my $gethost = check_host($_); my $gethost = check_host($server);
if ( !$gethost ) { if ( !$gethost ) {
my $text = "WARNING: '$_' unknown"; my $text = "WARNING: '$_' unknown";
@ -938,6 +971,12 @@ sub open_client_windows(@) {
} }
} }
my $count = q{};
while ( defined( $servers{ $server . q{ } . $count } ) ) {
$count++;
}
$server .= q{ } . $count;
$servers{$server}{realname} = $_; $servers{$server}{realname} = $_;
$servers{$server}{username} = $username; $servers{$server}{username} = $username;
$servers{$server}{port_nb} = $port_nb || ''; $servers{$server}{port_nb} = $port_nb || '';
@ -964,7 +1003,7 @@ sub open_client_windows(@) {
# affecting the main program # affecting the main program
$servers{$server}{realname} .= "==" if ( !$gethost ); $servers{$server}{realname} .= "==" if ( !$gethost );
my $exec my $exec
= "$config{terminal} $color $config{terminal_args} $config{terminal_allow_send_events} $config{terminal_title_opt} '$config{title}:$server' -font $config{terminal_font} -e \"$^X\" \"-e\" '$helper_script' '$servers{$server}{pipenm}' '$servers{$server}{realname}' '$servers{$server}{username}' '$servers{$server}{port_nb}'"; = "$config{terminal} $color $config{terminal_args} $config{terminal_allow_send_events} $config{terminal_title_opt} '$config{title}: $server' -font $config{terminal_font} -e \"$^X\" \"-e\" '$helper_script' '$servers{$server}{pipenm}' '$servers{$server}{realname}' '$servers{$server}{username}' '$servers{$server}{port_nb}'";
logmsg( 2, "Terminal exec line:\n$exec\n" ); logmsg( 2, "Terminal exec line:\n$exec\n" );
exec($exec) == 0 or warn("Failed: $!"); exec($exec) == 0 or warn("Failed: $!");
} }
@ -1433,9 +1472,9 @@ sub setup_repeat() {
if ( $config{internal_count} > 60000 ); # reset if too high if ( $config{internal_count} > 60000 ); # reset if too high
$config{internal_count}++; $config{internal_count}++;
my $build_menu = 0; my $build_menu = 0;
logmsg( 4, "Running repeat (count=$config{internal_count})" ); logmsg( 3, "Running repeat (count=$config{internal_count})" );
#logmsg( 4, "Number of servers in hash is: ", scalar( keys(%servers) ) ); #logmsg( 3, "Number of servers in hash is: ", scalar( keys(%servers) ) );
foreach my $svr ( keys(%servers) ) { foreach my $svr ( keys(%servers) ) {
if ( defined( $servers{$svr}{pid} ) ) { if ( defined( $servers{$svr}{pid} ) ) {
@ -1454,12 +1493,12 @@ sub setup_repeat() {
# get current number of clients # get current number of clients
$config{internal_total} = int( keys(%servers) ); $config{internal_total} = int( keys(%servers) );
#logmsg( 4, "Number after tidy is: ", $config{internal_total} ); #logmsg( 3, "Number after tidy is: ", $config{internal_total} );
# get current number of clients # get current number of clients
$config{internal_total} = int( keys(%servers) ); $config{internal_total} = int( keys(%servers) );
#logmsg( 4, "Number after tidy is: ", $config{internal_total} ); #logmsg( 3, "Number after tidy is: ", $config{internal_total} );
# If there are no hosts in the list and we are set to autoquit # If there are no hosts in the list and we are set to autoquit
if ( $config{internal_total} == 0 if ( $config{internal_total} == 0
@ -1479,7 +1518,7 @@ sub setup_repeat() {
# clean out text area, anyhow # clean out text area, anyhow
$menus{entrytext} = ""; $menus{entrytext} = "";
#logmsg( 4, "repeat completed" ); #logmsg( 3, "repeat completed" );
} }
); );
logmsg( 2, "Repeat setup" ); logmsg( 2, "Repeat setup" );
@ -1977,12 +2016,9 @@ cssh, crsh, ctel - Cluster administration tool
=head1 SYNOPSIS =head1 SYNOPSIS
S<< cssh [options] [[user@]<server>|<tag>] [...] >>
S<< crsh [options] [[user@]<server>|<tag>] [...] >>
S<< cssh [options] [[user@]<server>[:port]|<tag>] [...] >> S<< cssh [options] [[user@]<server>[:port]|<tag>] [...] >>
S<< crsh [options] [[user@]<server>[:port]|<tag>] [...] >> S<< crsh [options] [[user@]<server>[:port]|<tag>] [...] >>
S<< ctel [options] [<server>|<tag>] [...] >> S<< ctel [options] [<server>[:port]|<tag>] [...] >>
S<< ctel [options] [<server>|<tag>] [...] >>
=head1 DESCRIPTION =head1 DESCRIPTION
@ -2008,6 +2044,8 @@ changes are committed.
=head2 Further Notes =head2 Further Notes
Please also see L<KNOWN BUGS>.
=over =over
=item * =item *
@ -2475,25 +2513,50 @@ may also be disabled individually by setting to the word "null".
=back =back
=head1 AUTHOR
Duncan Ferguson
=head1 CREDITS
clusterssh is distributed under the GNU public license. See the file
F<LICENSE> for details.
A web site for comments, requests, bug reports and bug fixes/patches is
available at L<http://clusterssh.sourceforge.net/>
=head1 KNOWN BUGS =head1 KNOWN BUGS
Swapping virtual desktops can can a redraw of all the terminal windows. This =over 4
=item 1.
Catering for IPv6 addresses is minimal. This is due to a conflict
between IPv6 addresses and port numbers within the same
server definition since they both use the same seperator, i.e. is the
following just an IPv6 address, or an address + port number of 2323?
2001:db8::1428:2323
Exactly - I cannot tell either. the IPv6 address without a port is assumed
in those cases where it cannot be determined and a warning is issued.
Possible work arounds include:
=over 4
=item a.
Use the full IPv6 address if also using a port number - the 8th colon
is assumed to be the port seperator.
=item b.
Define the IPv6 address in your /etc/hosts file, DNS or other name service
lookup mechanism and use the hostname instead of the address.
=back
=item 2.
Swapping virtual desktops can a redraw of all the terminal windows. This
is due to a lack of distinction within Tk between switching desktops and is due to a lack of distinction within Tk between switching desktops and
minimising/maximising windows. Until Tk can tell the difference between the minimising/maximising windows. Until Tk can tell the difference between the
two events, there is no fix (apart from rewriting everything directly in X) two events, there is no fix (apart from rewriting everything directly in X)
=back
Anyone with any good ideas to fix the above bugs is more than welcome to get
in touch and/or provide a patch.
=head1 REPORTING BUGS =head1 REPORTING BUGS
=over 2 =over 2
@ -2550,4 +2613,16 @@ L<Tk::overview>,
L<X11::Protocol>, L<X11::Protocol>,
L<perl> L<perl>
=head1 AUTHOR
Duncan Ferguson
=head1 CREDITS
clusterssh is distributed under the GNU public license. See the file
F<LICENSE> for details.
A web site for comments, requests, bug reports and bug fixes/patches is
available at L<http://clusterssh.sourceforge.net/>
=cut =cut