Skip Menu |

This queue is for tickets about the Net-Patricia CPAN distribution.

Report information
The Basics
Id: 51481
Status: resolved
Worked: 4 hours (240 min)
Priority: 0/
Queue: Net-Patricia

People
Owner: PHILIPP [...] cpan.org
Requestors: TWILDE [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 1.15_01
Fixed in: (no value)



Subject: [PATCH] IPv6 support
Greetings! We've been using Net::Patricia patched locally with IPv6 support for almost three years now, and I realized that we've never submitted the patch upstream. It's actually pretty simple - I don't know if I'd call it pretty, and I'm not sure I can say it's "correct", but it does work for all uses we've tried it on in production. Attached is the patch, against the 1.15_01 development version from CPAN. A couple of quick notes: * We didn't patch the docs, sorry. Net::Patricia->new(AF_INET6) will give you a v6 trie, no args or AF_INET will give you a v4 trie. * The only quick simple test we came up with was this, not included in the patch: $t = new Net::Patricia (AF_INET6); $t->add_string('2001:220::/35', 'hello world'); my $match = $t->match_string('2001:220::/128'); print $match, "\n"; * libpatricia/patricia.c needed a sizeof(prefix_t) instead of sizeof(prefix6_t) in one location because prefix6_t isn't actually defined anywhere in the headers. * We just statically defined HAVE_IPV6, not sure if that would be better done through MakeMaker or something else. * A dependency is introduced for Socket6 - I thought this was in core, but a quick search seems to indicate it may not be. :| * The _ip_bits function was translated to an object method so it could return appropriately depending on whether or not the object was v4 or v6. Sorry that list is so long, hopefully we haven't created more work than we've saved. :| If you have specific requests for changes, ways to make the patch better/more acceptable, etc, please let me know and I'll see what I can do - making extra work for you as the package maintainer is definitely not my goal! Thanks, Tim Wilde
Subject: Net-Patricia-ipv6.patch
diff -u --recursive Net-Patricia-1.15_01/libpatricia/patricia.c Net-Patricia-1.15_01-mod/libpatricia/patricia.c --- Net-Patricia-1.15_01/libpatricia/patricia.c 2009-04-19 04:28:15.000000000 +0000 +++ Net-Patricia-1.15_01-mod/libpatricia/patricia.c 2009-11-12 17:12:00.000000000 +0000 @@ -226,7 +226,7 @@ if (family == AF_INET6) { default_bitlen = 128; if (prefix == NULL) { - prefix = calloc(1, sizeof (prefix6_t)); + prefix = calloc(1, sizeof (prefix_t)); dynamic_allocated++; } memcpy (&prefix->add.sin6, dest, 16); diff -u --recursive Net-Patricia-1.15_01/libpatricia/patricia.h Net-Patricia-1.15_01-mod/libpatricia/patricia.h --- Net-Patricia-1.15_01/libpatricia/patricia.h 2009-04-19 04:28:15.000000000 +0000 +++ Net-Patricia-1.15_01-mod/libpatricia/patricia.h 2009-11-12 16:47:17.000000000 +0000 @@ -15,6 +15,8 @@ #ifndef _PATRICIA_H #define _PATRICIA_H +#define HAVE_IPV6 + /* typedef unsigned int u_int; */ typedef void (*void_fn_t)(); /* { from defs.h */ diff -u --recursive Net-Patricia-1.15_01/Patricia.pm Net-Patricia-1.15_01-mod/Patricia.pm --- Net-Patricia-1.15_01/Patricia.pm 2009-07-31 17:45:55.000000000 +0000 +++ Net-Patricia-1.15_01-mod/Patricia.pm 2009-11-12 17:04:26.000000000 +0000 @@ -26,6 +26,7 @@ use Carp; use vars qw($VERSION @ISA); use Socket qw(AF_INET inet_aton inet_ntoa); +use Socket6 qw(AF_INET6 inet_pton inet_ntop); require DynaLoader; require 5.6.0; @@ -37,12 +38,17 @@ sub new { my ($class, $type) = @_; + $type ||= AF_INET; if ($type == AF_INET) { return bless _new(32), 'Net::Patricia::AF_INET'; } + if ($type == AF_INET6) { + return bless _new(128), 'Net::Patricia::AF_INET6'; + } + undef; } @@ -51,25 +57,31 @@ ## sub _ip_bits { - my $str = shift; - my $bits = ($str =~ s,/(\d+)$,,) ? $1 : 32; + my ($self, $str) = @_; + my $bits; + + if (ref ($self) eq 'Net::Patricia::AF_INET6') { + $bits = ($str =~ s,/(\d+)$,,) ? $1 : 128; + } else { + $bits = ($str =~ s,/(\d+)$,,) ? $1 : 32; + } ($str,$bits); } sub add_string { my ($self,$str,$data) = @_; $data = $str unless @_ > 2; - $self->add(_ip_bits($str),$data); + $self->add($self->_ip_bits($str),$data); } sub match_string { my ($self,$str) = @_; - $self->match(_ip_bits($str)) + $self->match($self->_ip_bits($str)) } sub match_exact_string { my ($self,$str) = @_; - $self->exact(_ip_bits($str)) + $self->exact($self->_ip_bits($str)) } sub match_exact_integer { @@ -78,7 +90,7 @@ sub remove_string { my ($self,$str) = @_; - $self->remove(_ip_bits($str)) + $self->remove($self->_ip_bits($str)) } ## @@ -135,6 +147,60 @@ _remove($self,AF_INET,pack("N",$num),(defined $bits ? $bits : 32)); } +## +## AF_INET6 +## + +@Net::Patricia::AF_INET6::ISA = qw(Net::Patricia); + +sub Net::Patricia::AF_INET6::add { + my ($self, $ip, $bits, $data) = @_; + $data ||= $bits ? "$ip/$bits" : $ip; + my $packed = inet_pton(AF_INET6, $ip) || croak("invalid key"); + _add($self,AF_INET6,$packed,(defined $bits ? $bits : 128), $data); +} + +sub Net::Patricia::AF_INET6::add_integer { + my ($self, $num, $bits, $data) = @_; + my $packed = pack("N", $num); + my $ip = inet_ntop(AF_INET6, $packed) || croak("invalid address"); + $data ||= defined $bits ? "$ip/$bits" : $ip; + _add($self,AF_INET6,$packed,(defined $bits ? $bits : 128), $data); +} + +sub Net::Patricia::AF_INET6::match_integer { + my ($self, $num, $bits) = @_; + _match($self,AF_INET6,pack("N",$num),(defined $bits ? $bits : 128)); +} + +sub Net::Patricia::AF_INET6::exact_integer { + my ($self, $num, $bits) = @_; + _exact($self,AF_INET6,pack("N",$num),(defined $bits ? $bits : 128)); +} + +sub Net::Patricia::AF_INET6::match { + my ($self, $ip, $bits) = @_; + my $packed = inet_pton(AF_INET6, $ip) || croak("invalid key"); + _match($self,AF_INET6,$packed,(defined $bits ? $bits : 128)); +} + +sub Net::Patricia::AF_INET6::exact { + my ($self, $ip, $bits) = @_; + my $packed = inet_pton(AF_INET6, $ip) || croak("invalid key"); + _exact($self,AF_INET6,$packed,(defined $bits ? $bits : 128)); +} + +sub Net::Patricia::AF_INET6::remove { + my ($self, $ip, $bits) = @_; + my $packed = inet_pton(AF_INET6, $ip) || return undef; + _remove($self,AF_INET6,$packed,(defined $bits ? $bits : 128)); +} + +sub Net::Patricia::AF_INET6::remove_integer { + my ($self, $num, $bits) = @_; + _remove($self,AF_INET6,pack("N",$num),(defined $bits ? $bits : 128)); +} + 1; __END__ # Below is the stub of documentation for your module. You better edit it!
Fixed in 1.15_06.