[PATCH] ipv6

Brian McArdle brianmc at gmail.com
Mon Jun 25 12:16:42 UTC 2007


Skipped content of type multipart/alternative-------------- next part --------------

Index: memcached.c
===================================================================
--- memcached.c (revision 572)
+++ memcached.c (working copy)
@@ -2516,13 +2516,14 @@
         case 'l':
-            if (inet_pton(AF_INET, optarg, &addr) <= 0) {
-                fprintf(stderr, "Illegal address: %s\n", optarg);
-                return 1;
-            } else {
-                settings.interf = addr;
-            }
-            break;
+           if (inet_pton(AF_INET, optarg, &addr) <= 0) {
+               if (inet_pton(AF_INET6, optarg, &addr) <= 0) {
+                   fprintf(stderr, "Illegal address: %s\n", optarg);
+                   return 1;
+               }
+           }
+           settings.interf = addr;
+           break;




Index: lib/Cache/Memcached.pm
===================================================================
--- lib/Cache/Memcached.pm      (revision 572)
+++ lib/Cache/Memcached.pm      (working copy)
@@ -13,6 +13,7 @@
 no strict 'refs';
 use Storable ();
 use Socket qw( MSG_NOSIGNAL PF_INET PF_UNIX IPPROTO_TCP SOCK_STREAM );
+use Socket6 qw( AF_INET6 );
 use IO::Handle ();
 use Time::HiRes ();
 use String::CRC32;
@@ -25,6 +26,7 @@
     bucketcount _single_sock _stime
     connect_timeout cb_connect_fail
     parser_class
+    addr_fam
 };

 # flag definitions
@@ -82,6 +84,7 @@
     $self->{'select_timeout'}  = $args->{'select_timeout'}  || 1.0;
     $self->{namespace} = $args->{namespace} || '';
     $self->{namespace_len} = length $self->{namespace};
+    $self->{addr_fam} = $args->{'addr_fam'};

     return $self;
 }
@@ -230,7 +233,12 @@
     return $cache_sock{$host} if $cache_sock{$host};

     my $now = time();
-    my ($ip, $port) = $host =~ /(.*):(\d+)/;
+    my ($ip, $port);
+    if ( $self->{addr_fam} == 4 ) {
+        ($ip, $port) = $host =~ /(.*):(\d+)/;
+    } else {
+        ($ip, $port) = $host =~ /\[([a-fA-F0-9:]*)\]:(\d+)/;
+    }
     return undef if
         $host_dead{$host} && $host_dead{$host} > $now;
     my $sock;
@@ -243,9 +251,14 @@
     {
         # if a preferred IP is known, try that first.
         if ($self && $self->{pref_ip}{$ip}) {
-            socket($sock, PF_INET, SOCK_STREAM, $proto);
             my $prefip = $self->{pref_ip}{$ip};
-            $sin = Socket::sockaddr_in($port,Socket::inet_aton($prefip));
+           if ( $self->{addr_fam} == 4 ) {
+                socket($sock, PF_INET, SOCK_STREAM, $proto);
+                $sin = Socket::sockaddr_in($port,Socket::inet_aton($prefip));
+           } else {
+                socket($sock, AF_INET6, SOCK_STREAM, $proto);
+                $sin = Socket6::sockaddr_in6($port,Socket::inet_pton(AF_INET6, $prefip));
+           }
             if (_connect_sock($sock,$sin,$self->{connect_timeout})) {
                 $connected = 1;
             } else {
@@ -258,8 +271,13 @@

         # normal path, or fallback path if preferred IP failed
         unless ($connected) {
-            socket($sock, PF_INET, SOCK_STREAM, $proto);
-            $sin = Socket::sockaddr_in($port,Socket::inet_aton($ip));
+           if ( $self->{addr_fam} == 4 ) {
+                socket($sock, PF_INET, SOCK_STREAM, $proto);
+                $sin = Socket::sockaddr_in($port,Socket::inet_aton($ip));
+           } else {
+                socket($sock, AF_INET6, SOCK_STREAM, $proto);
+                $sin = Socket6::sockaddr_in6($port,Socket6::inet_pton(AF_INET6, $ip));
+           }
             my $timeout = $self ? $self->{connect_timeout} : 0.25;
             unless (_connect_sock($sock,$sin,$timeout)) {
                 my $cb = $self ? $self->{cb_connect_fail} : undef;
@@ -269,7 +287,11 @@
         }
     } else { # it's a unix domain/local socket
         socket($sock, PF_UNIX, SOCK_STREAM, 0);
-        $sin = Socket::sockaddr_un($host);
+       if ( $self->{addr_fam} == 4 ) {
+            $sin = Socket::sockaddr_un($host);
+       } else {
+            $sin = Socket6::sockaddr_un6($host);
+       }
         my $timeout = $self ? $self->{connect_timeout} : 0.25;
         unless (_connect_sock($sock,$sin,$timeout)) {
             my $cb = $self ? $self->{cb_connect_fail} : undef;



Index: t/all.t
===================================================================
--- t/all.t     (revision 572)
+++ t/all.t     (working copy)
@@ -1,13 +1,36 @@
-# -*-perl-*-
+#!/usr/bin/perl

 use strict;
+use lib '../lib';
 use Test::More;
 use Cache::Memcached;
 use IO::Socket::INET;
+use IO::Socket::INET6;
+use Getopt::Long;

-my $testaddr = "127.0.0.1:11211";
-my $msock = IO::Socket::INET->new(PeerAddr => $testaddr,
+my $testaddr;
+my $msock;
+my $addr_fam = 4;
+
+GetOptions('6:i' => sub{$addr_fam = 6},
+          '4:i' => sub{$addr_fam = 4},
+          'l:s' => \$testaddr
+         );
+
+if ( $addr_fam == 6 ) {
+    if ( !defined $testaddr ) {
+        $testaddr = "[::ffff:7f00:0001]:11211";
+    }
+    $msock = IO::Socket::INET6->new(PeerAddr => $testaddr,
                                   Timeout  => 3);
+} else {
+    if ( !defined $testaddr ) {
+        $testaddr = "127.0.0.1:11211";
+    }
+    $msock = IO::Socket::INET->new(PeerAddr => $testaddr,
+                                  Timeout  => 3);
+}
+
 if ($msock) {
     plan tests => 9;
 } else {
@@ -18,6 +41,7 @@
 my $memd = Cache::Memcached->new({
     servers   => [ $testaddr ],
     namespace => "Cache::Memcached::t/$$/" . (time() % 100) . "/",
+    addr_fam => $addr_fam
 });

 ok($memd->set("key1", "val1"), "set succeeded");


More information about the memcached mailing list