Subject: | Patch for IPv6 support in Cache::Memcached 1.27 |
memcached supports IPv6 sockets, but the perl client isn't IPv6-aware.
Patch is included to make Cache::Memcached IPv6-aware, while falling
back gracefully on clients that do not have Socket6.pm.
Thanks!
Subject: | Cache-Memcached-1.27-ipv6.patch |
--- Memcached.pm.old 2009-10-16 15:23:14.000000000 -0700
+++ Memcached.pm 2009-10-16 15:24:34.000000000 -0700
@@ -36,7 +36,7 @@
use constant COMPRESS_SAVINGS => 0.20; # percent
use vars qw($VERSION $HAVE_ZLIB $FLAG_NOSIGNAL);
-$VERSION = "1.27";
+$VERSION = "1.27.4663";
BEGIN {
$HAVE_ZLIB = eval "use Compress::Zlib (); 1;";
@@ -231,7 +231,9 @@
return $cache_sock{$host} if $cache_sock{$host};
my $now = time();
- my ($ip, $port) = $host =~ /(.*):(\d+)/;
+ my ($ip, $port) = $host =~ /(.*):(\d+)$/;
+ $ip =~ s/[\[\]]//g; # get rid of optional IPv6 brackets
+
return undef if
$host_dead{$host} && $host_dead{$host} > $now;
my $sock;
@@ -244,10 +246,24 @@
{
# if a preferred IP is known, try that first.
if ($self && $self->{pref_ip}{$ip}) {
- socket($sock, PF_INET, SOCK_STREAM, $proto);
- $sock_map{$sock} = $host;
+ my $v6ok;
my $prefip = $self->{pref_ip}{$ip};
- $sin = Socket::sockaddr_in($port,Socket::inet_aton($prefip));
+ if (index($prefip,':')) { # Try IPv6
+ eval {
+ use Socket6 qw(AF_INET6 PF_INET6);
+ socket($sock, PF_INET6, SOCK_STREAM, $proto);
+ $sock_map{$sock} = $host;
+ $sin = Socket6::pack_sockaddr_in6($port,Socket6::inet_pton(AF_INET6,$prefip));
+ $v6ok = 1;
+ };
+ }
+
+ unless ($v6ok) {
+ socket($sock, PF_INET, SOCK_STREAM, $proto);
+ $sock_map{$sock} = $host;
+ $sin = Socket::sockaddr_in($port,Socket::inet_aton($prefip));
+ }
+
if (_connect_sock($sock,$sin,$self->{connect_timeout})) {
$connected = 1;
} else {
@@ -260,9 +276,23 @@
# normal path, or fallback path if preferred IP failed
unless ($connected) {
- socket($sock, PF_INET, SOCK_STREAM, $proto);
- $sock_map{$sock} = $host;
- $sin = Socket::sockaddr_in($port,Socket::inet_aton($ip));
+ my $v6ok;
+ if (index($ip,':')) { # Try IPv6
+ eval {
+ use Socket6 qw(AF_INET6 PF_INET6);
+ socket($sock, PF_INET6, SOCK_STREAM, $proto);
+ $sock_map{$sock} = $host;
+ $sin = Socket6::pack_sockaddr_in6($port,Socket6::inet_pton(AF_INET6,$ip));
+ $v6ok = 1;
+ };
+ }
+
+ unless ($v6ok) {
+ socket($sock, PF_INET, SOCK_STREAM, $proto);
+ $sock_map{$sock} = $host;
+ $sin = Socket::sockaddr_in($port,Socket::inet_aton($ip));
+ }
+
my $timeout = $self ? $self->{connect_timeout} : 0.25;
unless (_connect_sock($sock,$sin,$timeout)) {
my $cb = $self ? $self->{cb_connect_fail} : undef;