Blame SOURCES/Net-DNS-0.72-Memory-leak.patch

b0009a
Index: lib/Net/DNS/Packet.pm
b0009a
===================================================================
b0009a
--- lib/Net/DNS/Packet.pm	(revision 1099)
b0009a
+++ lib/Net/DNS/Packet.pm	(working copy)
b0009a
@@ -30,7 +30,6 @@
b0009a
 use base Exporter;
b0009a
 @EXPORT_OK = qw(dn_expand);
b0009a
 
b0009a
-use strict;
b0009a
 use integer;
b0009a
 use Carp;
b0009a
 
b0009a
@@ -67,7 +66,8 @@
b0009a
 		authority  => [],
b0009a
 		additional => []}, $class;
b0009a
 
b0009a
-	$self->{question} = [Net::DNS::Question->new(@_)] if @_;
b0009a
+	$self->{question} = [Net::DNS::Question->new(@_)] if scalar @_;
b0009a
+	$self->{header} = {}; # For compatibility with Net::DNS::SEC
b0009a
 
b0009a
 	$self->header->rd(1);
b0009a
 	return $self;
b0009a
@@ -114,20 +114,23 @@
b0009a
 	eval {
b0009a
 		die 'corrupt wire-format data' if length($$data) < HEADER_LENGTH;
b0009a
 
b0009a
+		# header section
b0009a
+		my ( $id, $status, @count ) = unpack 'n6', $$data;
b0009a
+		my ( $qd, $an, $ns, $ar ) = @count;
b0009a
+		$offset = HEADER_LENGTH;
b0009a
+
b0009a
 		$self = bless {
b0009a
+			id	   => $id,
b0009a
+			status	   => $status,
b0009a
+			count	   => [@count],
b0009a
 			question   => [],
b0009a
 			answer	   => [],
b0009a
 			authority  => [],
b0009a
 			additional => [],
b0009a
-			answersize => length $$data
b0009a
+			answersize => length $$data,
b0009a
+			header     => {} # Compatibility with Net::DNS::SEC
b0009a
 			}, $class;
b0009a
 
b0009a
-		# header section
b0009a
-		my $header = $self->header;
b0009a
-		$header->decode($data);
b0009a
-		my ( $qd, $an, $ns, $ar ) = map { $header->$_ } qw(qdcount ancount nscount arcount);
b0009a
-		$offset = HEADER_LENGTH;
b0009a
-
b0009a
 		# question/zone section
b0009a
 		my $hash = {};
b0009a
 		my $record;
b0009a
@@ -178,18 +181,21 @@
b0009a
 sub data {
b0009a
 	my $self = shift;
b0009a
 
b0009a
-	for ( my $edns = $self->edns ) {			# EDNS support
b0009a
+	my $header = $self->header;				# packet header
b0009a
+	my $ident  = $header->id;
b0009a
+
b0009a
+	for ( my $edns = $header->edns ) {			# EDNS support
b0009a
 		my @xopt = grep { $_->type ne 'OPT' } @{$self->{additional}};
b0009a
 		$self->{additional} = $edns->default ? [@xopt] : [$edns, @xopt];
b0009a
 	}
b0009a
 
b0009a
-	my $data = $self->header->encode;			# packet header
b0009a
+	my @part = qw(question answer authority additional);
b0009a
+	my @size = map scalar( @{$self->{$_}} ), @part;
b0009a
+	my $data = pack 'n6', $ident, $self->{status}, @size;
b0009a
+	$self->{count} = [];
b0009a
 
b0009a
 	my $hash = {};						# packet body
b0009a
-	foreach my $component ( @{$self->{question}},
b0009a
-				@{$self->{answer}},
b0009a
-				@{$self->{authority}},
b0009a
-				@{$self->{additional}}	) {
b0009a
+	foreach my $component ( map @{$self->{$_}}, @part ) {
b0009a
 		$data .= $component->encode( length $data, $hash, $self );
b0009a
 	}
b0009a
 
b0009a
@@ -208,8 +214,7 @@
b0009a
 =cut
b0009a
 
b0009a
 sub header {
b0009a
-	my $self = shift;
b0009a
-	$self->{header} ||= new Net::DNS::Header($self);
b0009a
+	return new Net::DNS::Header(shift);
b0009a
 }
b0009a
 
b0009a
 
b0009a
@@ -243,19 +248,20 @@
b0009a
 sub reply {
b0009a
 	my $query  = shift;
b0009a
 	my $UDPmax = shift;
b0009a
-	die 'erroneous qr flag in query packet' if $query->header->qr;
b0009a
+	my $qheadr = $query->header;
b0009a
+	die 'erroneous qr flag in query packet' if $qheadr->qr;
b0009a
 
b0009a
 	my $reply  = new Net::DNS::Packet();
b0009a
-	my $header = $reply->header;
b0009a
-	$header->qr(1);						# reply with same id, opcode and question
b0009a
-	$header->id( $query->header->id );
b0009a
-	$header->opcode( $query->header->opcode );
b0009a
-	$reply->{question} = [$query->question];
b0009a
+	my $rheadr = $reply->header;
b0009a
+	$rheadr->qr(1);						# reply with same id, opcode and question
b0009a
+	$rheadr->id( $qheadr->id );
b0009a
+	$rheadr->opcode( $qheadr->opcode );
b0009a
+	$reply->{question} = $query->{question};
b0009a
 
b0009a
-	$header->rcode('FORMERR');				# failure to provide RCODE is sinful!
b0009a
+	$rheadr->rcode('FORMERR');				# failure to provide RCODE is sinful!
b0009a
 
b0009a
-	$header->rd( $query->header->rd );			# copy these flags into reply
b0009a
-	$header->cd( $query->header->cd );
b0009a
+	$rheadr->rd( $qheadr->rd );				# copy these flags into reply
b0009a
+	$rheadr->cd( $qheadr->cd );
b0009a
 
b0009a
 	$reply->edns->size($UDPmax) unless $query->edns->default;
b0009a
 	return $reply;
b0009a
@@ -405,7 +411,7 @@
b0009a
 sub answerfrom {
b0009a
 	my $self = shift;
b0009a
 
b0009a
-	return $self->{answerfrom} = shift if @_;
b0009a
+	return $self->{answerfrom} = shift if scalar @_;
b0009a
 
b0009a
 	return $self->{answerfrom};
b0009a
 }
b0009a
@@ -778,7 +784,7 @@
b0009a
 			my $i=0;
b0009a
 			my @stripped_additonal;
b0009a
 
b0009a
-			while ($i< @{$self->{'additional'}}){
b0009a
+			while ( $i < scalar @{$self->{'additional'}} ) {
b0009a
 				#remove all of these same RRtypes
b0009a
 				if  (
b0009a
 				    ${$self->{'additional'}}[$i]->type eq $popped->type &&
b0009a
@@ -814,21 +820,16 @@
b0009a
 
b0009a
 use vars qw($AUTOLOAD);
b0009a
 
b0009a
-sub AUTOLOAD {				## Default method
b0009a
+sub AUTOLOAD {			## Default method
b0009a
 	no strict;
b0009a
 	@_ = ("method $AUTOLOAD undefined");
b0009a
 	goto &{'Carp::confess'};
b0009a
 }
b0009a
 
b0009a
-sub DESTROY {				## object destructor
b0009a
-	my $self = shift;
b0009a
-	my $header = $self->header;				# invalidate Header object
b0009a
-	%$header = ();
b0009a
-	undef $self->{header};					# unlink defunct header
b0009a
-}
b0009a
+sub DESTROY { }			## Avoid tickling AUTOLOAD (in cleanup)
b0009a
 
b0009a
 
b0009a
-sub dump {				## print internal data structure
b0009a
+sub dump {			## print internal data structure
b0009a
 	use Data::Dumper;
b0009a
 	$Data::Dumper::Sortkeys = sub { return [sort keys %{$_[0]}] };
b0009a
 	my $self = shift;
b0009a
Index: lib/Net/DNS/Header.pm
b0009a
===================================================================
b0009a
--- lib/Net/DNS/Header.pm	(revision 1099)
b0009a
+++ lib/Net/DNS/Header.pm	(working copy)
b0009a
@@ -51,56 +51,10 @@
b0009a
 
b0009a
 	croak 'object model violation' unless $packet->isa(qw(Net::DNS::Packet));
b0009a
 
b0009a
-	my $self = bless {
b0009a
-		status => 0,
b0009a
-		count  => [],
b0009a
-		xbody  => $packet
b0009a
-		}, $class;
b0009a
-
b0009a
-	$self->id(undef);
b0009a
-
b0009a
-	return $self;
b0009a
+	bless { xbody => $packet }, $class;
b0009a
 }
b0009a
 
b0009a
 
b0009a
-=head2 decode
b0009a
-
b0009a
-	$header->decode(\$data);
b0009a
-
b0009a
-Decodes the header record at the start of a DNS packet.
b0009a
-The argument is a reference to the packet data.
b0009a
-
b0009a
-=cut
b0009a
-
b0009a
-sub decode {
b0009a
-	my $self = shift;
b0009a
-	my $data = shift;
b0009a
-
b0009a
-	@{$self}{qw(id status)} = unpack 'n2', $$data;
b0009a
-	$self->{count} = [unpack 'x4 n6', $$data];
b0009a
-}
b0009a
-
b0009a
-
b0009a
-=head2 encode
b0009a
-
b0009a
-	$header->encode(\$data);
b0009a
-
b0009a
-Returns the header data in binary format, appropriate for use in a
b0009a
-DNS packet.
b0009a
-
b0009a
-=cut
b0009a
-
b0009a
-sub encode {
b0009a
-	my $self = shift;
b0009a
-
b0009a
-	$self->{count} = [];
b0009a
-
b0009a
-	my @count = map { $self->$_ } qw(qdcount ancount nscount arcount);
b0009a
-
b0009a
-	return pack 'n6', $self->{id}, $self->{status}, @count;
b0009a
-}
b0009a
-
b0009a
-
b0009a
 =head2 string
b0009a
 
b0009a
     print $packet->header->string;
b0009a
@@ -121,11 +75,15 @@
b0009a
 	my $ns	   = $self->nscount;
b0009a
 	my $ar	   = $self->arcount;
b0009a
 
b0009a
+	my $opt = $self->edns;
b0009a
+	my $edns = ( $opt->isa(qw(Net::DNS::RR::OPT)) && not $opt->default ) ? $opt->string : '';
b0009a
+
b0009a
 	my $retval;
b0009a
 	return $retval = <
b0009a
 ;;	id = $id
b0009a
 ;;	qr = $qr		opcode = $opcode	rcode = $rcode
b0009a
 ;;	zocount = $qd	prcount = $an	upcount = $ns	adcount = $ar
b0009a
+$edns
b0009a
 EOF
b0009a
 
b0009a
 	my $aa = $self->aa;
b0009a
@@ -137,9 +95,6 @@
b0009a
 	my $cd = $self->cd;
b0009a
 	my $do = $self->do;
b0009a
 
b0009a
-	my $opt = $self->edns;
b0009a
-	my $edns = ( $opt->isa(qw(Net::DNS::RR::OPT)) && not $opt->default ) ? $opt->string : '';
b0009a
-
b0009a
 	return $retval = <
b0009a
 ;;	id = $id
b0009a
 ;;	qr = $qr	aa = $aa	tc = $tc	rd = $rd	opcode = $opcode
b0009a
@@ -166,8 +121,9 @@
b0009a
 
b0009a
 sub id {
b0009a
 	my $self = shift;
b0009a
-	return $self->{id} unless @_;
b0009a
-	return $self->{id} = shift || int rand(0xffff);
b0009a
+	my $xpkt = $self->{xbody};
b0009a
+	$xpkt->{id} = shift if scalar @_;
b0009a
+	$xpkt->{id} ||= int rand(0xffff);
b0009a
 }
b0009a
 
b0009a
 
b0009a
@@ -182,8 +138,9 @@
b0009a
 
b0009a
 sub opcode {
b0009a
 	my $self = shift;
b0009a
-	for ( $self->{status} ) {
b0009a
-		return opcodebyval( ( $_ >> 11 ) & 0x0f ) unless @_;
b0009a
+	my $xpkt = $self->{xbody};
b0009a
+	for ( $xpkt->{status} ||= 0 ) {
b0009a
+		return opcodebyval( ( $_ >> 11 ) & 0x0f ) unless scalar @_;
b0009a
 		my $opcode = opcodebyname(shift);
b0009a
 		$_ = ( $_ & 0x87ff ) | ( $opcode << 11 );
b0009a
 		return $opcode;
b0009a
@@ -202,7 +159,8 @@
b0009a
 
b0009a
 sub rcode {
b0009a
 	my $self = shift;
b0009a
-	for ( $self->{status} ) {
b0009a
+	my $xpkt = $self->{xbody};
b0009a
+	for ( $xpkt->{status} ||= 0 ) {
b0009a
 		my $arg = shift;
b0009a
 		my $opt = $self->edns;
b0009a
 		unless ( defined $arg ) {
b0009a
@@ -335,7 +293,7 @@
b0009a
 
b0009a
     print "# of question records: ", $packet->header->qdcount, "\n";
b0009a
 
b0009a
-Gets the number of records in the question section of the packet.
b0009a
+Returns the number of records in the question section of the packet.
b0009a
 In dynamic update packets, this field is known as C<zocount> and refers
b0009a
 to the number of RRs in the zone section.
b0009a
 
b0009a
@@ -346,7 +304,7 @@
b0009a
 sub qdcount {
b0009a
 	my $self = shift;
b0009a
 	my $xpkt = $self->{xbody};
b0009a
-	return $self->{count}[0] || scalar @{$xpkt->{question}} unless @_;
b0009a
+	return $xpkt->{count}[0] || scalar @{$xpkt->{question}} unless scalar @_;
b0009a
 	carp 'header->qdcount attribute is read-only' unless $warned;
b0009a
 }
b0009a
 
b0009a
@@ -366,7 +324,7 @@
b0009a
 sub ancount {
b0009a
 	my $self = shift;
b0009a
 	my $xpkt = $self->{xbody};
b0009a
-	return $self->{count}[1] || scalar @{$xpkt->{answer}} unless @_;
b0009a
+	return $xpkt->{count}[1] || scalar @{$xpkt->{answer}} unless scalar @_;
b0009a
 	carp 'header->ancount attribute is read-only' unless $warned;
b0009a
 }
b0009a
 
b0009a
@@ -386,7 +344,7 @@
b0009a
 sub nscount {
b0009a
 	my $self = shift;
b0009a
 	my $xpkt = $self->{xbody};
b0009a
-	return $self->{count}[2] || scalar @{$xpkt->{authority}} unless @_;
b0009a
+	return $xpkt->{count}[2] || scalar @{$xpkt->{authority}} unless scalar @_;
b0009a
 	carp 'header->nscount attribute is read-only' unless $warned;
b0009a
 }
b0009a
 
b0009a
@@ -405,7 +363,7 @@
b0009a
 sub arcount {
b0009a
 	my $self = shift;
b0009a
 	my $xpkt = $self->{xbody};
b0009a
-	return $self->{count}[3] || scalar @{$xpkt->{additional}} unless @_;
b0009a
+	return $xpkt->{count}[3] || scalar @{$xpkt->{additional}} unless scalar @_;
b0009a
 	carp 'header->arcount attribute is read-only' unless $warned;
b0009a
 }
b0009a
 
b0009a
@@ -469,11 +427,11 @@
b0009a
 =cut
b0009a
 
b0009a
 sub edns {
b0009a
-	my $self    = shift;
b0009a
-	my $xpkt    = $self->{xbody};
b0009a
-	my $xtender = \$self->{xtender};
b0009a
-	($$xtender) = grep { $_->type eq 'OPT' } @{$xpkt->{additional}} unless $$xtender;
b0009a
-	return $$xtender ||= new Net::DNS::RR('. OPT');
b0009a
+	my $self = shift;
b0009a
+	my $xpkt = $self->{xbody};
b0009a
+	my $link = \$xpkt->{xedns};
b0009a
+	($$link) = grep { $_->type eq 'OPT' } @{$xpkt->{additional}} unless $$link;
b0009a
+	return $$link ||= new Net::DNS::RR('. OPT');
b0009a
 }
b0009a
 
b0009a
 
b0009a
@@ -481,31 +439,23 @@
b0009a
 
b0009a
 use vars qw($AUTOLOAD);
b0009a
 
b0009a
-sub AUTOLOAD {				## Default method
b0009a
+sub AUTOLOAD {			## Default method
b0009a
 	no strict;
b0009a
 	@_ = ("method $AUTOLOAD undefined");
b0009a
 	goto &{'Carp::confess'};
b0009a
 }
b0009a
 
b0009a
-sub DESTROY { }				## Avoid tickling AUTOLOAD (in cleanup)
b0009a
+sub DESTROY { }			## Avoid tickling AUTOLOAD (in cleanup)
b0009a
 
b0009a
 
b0009a
-sub dump {				## print internal data structure
b0009a
-	use Data::Dumper;
b0009a
-	$Data::Dumper::Sortkeys = sub { return [sort keys %{$_[0]}] };
b0009a
-	my $self = shift;
b0009a
-	return Dumper($self) if defined wantarray;
b0009a
-	print Dumper($self);
b0009a
-}
b0009a
-
b0009a
-
b0009a
 sub _dnsflag {
b0009a
 	my $self = shift;
b0009a
 	my $flag = shift;
b0009a
-	for ( $self->{status} ) {
b0009a
+	my $xpkt = $self->{xbody};
b0009a
+	for ( $xpkt->{status} ||= 0 ) {
b0009a
 		my $set = $_ | $flag;
b0009a
 		my $not = $set - $flag;
b0009a
-		$_ = (shift) ? $set : $not if @_;
b0009a
+		$_ = (shift) ? $set : $not if scalar @_;
b0009a
 		return ( $_ & $flag ) ? 1 : 0;
b0009a
 	}
b0009a
 }
b0009a
@@ -515,7 +465,7 @@
b0009a
 	my $self = shift;
b0009a
 	my $flag = shift;
b0009a
 	my $edns = eval { $self->edns->flags } || 0;
b0009a
-	return $flag & $edns ? 1 : 0 unless @_;
b0009a
+	return $flag & $edns ? 1 : 0 unless scalar @_;
b0009a
 	my $set = $flag | $edns;
b0009a
 	my $not = $set - $flag;
b0009a
 	my $new = (shift) ? $set : $not;