gokuraku has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

Since I now have a working TCP client and server running I am looking to incorporate IPv6 into my work. I'm not quite sure how to go about this. I am using the standard Perl Cookbook to make my servers and clients, basically with IO::Socket::INET

$server = IO::Socket::INET->new(LocalAddr => "$localHost:$socket_port +", Proto => $protocol, Reuse => 1, Listen => $conn) or die "Can't make $protocol server on port $socket_port: $@\n +"; print "Running on port $socket_port.\n" if $verbose;

So if am looking to incorporate Socket6 into my program, to have a different IP version get built, can I still use this code to generate it? Would I just need to import Socket6 in an instance that I need IPv6? I know in C you need to use AF_INET6 instead of AF_INET, but I can't quite figure out how to do this with Socket6.

I got directed to Socket6 in trying to search for IPv6 clients or servers, haven't found much in the way of examples for what I need to do yet. Any help is appreciated.

Thanks!

Replies are listed 'Best First'.
Re: Getting IPv6 with the Cookbook
by ikegami (Patriarch) on Dec 18, 2007 at 19:55 UTC
    use IO::Socket::INET qw( AF_INET ); use IO::Socket::INET6 qw( AF_INET6 ); my $server = IO::Socket->new( Domain => ($ip6 ? AF_INET6 : AF_INET), Proto => 'tcp', # Makes sense for this to be variable. LocalHost => $localHost, # You sure you want this? Rarely do. LocalPort => $socket_port, Reuse => 1, Listen => $conn, ) or die "Can't make $protocol server on port $socket_port: $@\n"; print "Running on port $socket_port.\n" if $verbose;

    It makes no sense for Proto to be variable since TCP and UDP programs are quite different.

    Specifying LocalHost limits the interfaces that can receive the connection. If you wish to only accept connections from the local machine, you'd set this to '127.0.0.1'. Otherwise, don't use this.

      Here is the final code I generated:

      sub make_server { my ($ipv6,$localHost,$conn,$protocol,$socket_port,$verbose) = @_; my $server; print "Using protocol = $protocol on $localHost with port = $socket +_port.\n" if $verbose; if ($ipv6) { print "Running IPv6 tests.\n" if $verbose; $server = IO::Socket::INET6->new(LocalAddr => "$localHost:$soc +ket_port", Proto => $protocol, Reuse => 1, Listen => $conn) or die "Couldn't make IPv6 server on port $socket_port: $@\n"; print "Running IPv6 enabled on port $socket_port.\n" if $verbos +e; } else { print "Running IPv4 tests.\n" if $verbose; $server = IO::Socket::INET->new(LocalAddr => "$localHost:$sock +et_port", Proto => $protocol, Reuse => 1, Listen => $conn) or die "Can't make $protocol server on port $socket_port: $@\n +"; print "Running on port $socket_port.\n" if $verbose; } return($server); }

      A little about this code....it's made to use the $protocol flag to handle some test cases for TCP and UDP, the Server starts up and handles a Client that connects using similar code to start up with the same conditions. What I was trying to handle was not only IPv4 but IPv6, plus conditions for TCP and UDP so I can just send flags to the creation of the Server or Client and have them generate what I need.

      Of course none of this addresses the fact that I also need to make something with Named Pipes for Windows, but that's another story.

Re: Getting IPv6 with the Cookbook
by weismat (Friar) on Dec 18, 2007 at 18:27 UTC
    I would assume that you need to use IO::Socket::INET6 instead of IO::Socket::INET. No further changes should be required from my pov as the interface to the socket implementation should be stable.

      Ok, that library was new to me, I had done some searching and all I found was Socket6. Didn't think about INET6 on that one, my bad.

      Now this gets a little off topic, but in the setup I have we have a small Perl distro with the specific libraries we are using, mostly homemade modules and such, plus libraries like INET and INET6. I added this one as usual, and it needed Socket6, which I did have but was not using. Though when I try and run my program I get:
      Can't locate object method "bootstrap" via package "Socket6" (perhaps you forgot to load "Socket6"?) at C:/work/emx-qa/M OTH/newdummy/../Perl/IO/Socket/Socket6.pm line 289.
      Compilation failed in require at C:/work/emx-qa/MOTH/newdummy/../Perl/IO/Socket/INET6.pm line 18.
      BEGIN failed--compilation aborted at C:/work/emx-qa/MOTH/newdummy/../Perl/IO/Socket/INET6.pm line 18.
      Compilation failed in require at dummyserver.pl line 22.
      BEGIN failed--compilation aborted at dummyserver.pl line 22.

      I haven't hit AutoLoader stuff much in the past, and basically I have always been able to just add pm files to the right locations in our distro and have no issues. But this one seems off, and I can't seem to find more about it. Do I need to add a bootstrap function to the library file? I noticed another library file had it there, but this one does not, I just grabbed Socket6 and the others from CPAN and put them in the right locations.

      Going to keep looking, but anything else is appreciated. Really glad for the help here, and once I get this running I'll put up the working code.

      Ciao

        One bad thing I did was comment out the bootstrap line in the Socket6.pm file (bootstrap Socket6 $VERSION;), that tends to cause the following loop to occur when trying to create the server.

        my($constname); ($constname = $AUTOLOAD) =~ s/.*:://; my $val = constant($constname, @_ ? $_[0] : 0);

        Which is the beginning of the AutoLoad function in Socket6.pm

        sub AUTOLOAD { my($constname); ($constname = $AUTOLOAD) =~ s/.*:://; my $val = constant($constname, @_ ? $_[0] : 0); if ($! != 0) { if ($! =~ /Invalid/) { $AutoLoader::AUTOLOAD = $AUTOLOAD; goto &AutoLoader::AUTOLOAD; } else { my ($pack,$file,$line) = caller; croak "Your vendor has not defined Socket macro $constname, us +ed"; } } eval "sub $AUTOLOAD { $val }"; goto &$AUTOLOAD; }

        This also has the effect of taking memory away from the machine until it runs out, a good way to starve the machine if you need to do that I suppose. But definitely not what I would like to have happen.