@@ -263,8 +263,8 @@ Packet.prototype.toBuffer = function(writer) {
263263 ] ) . forEach ( function ( def ) {
264264 const section = def [ 0 ] ;
265265 const Encoder = def [ 1 ] ;
266- ( this [ section ] || [ ] ) . map ( function ( resource ) {
267- return Encoder . encode ( resource , writer ) ;
266+ ( this [ section ] || [ ] ) . forEach ( function ( resource ) {
267+ Encoder . encode ( resource , writer ) ;
268268 } ) ;
269269 } . bind ( this ) ) ;
270270 return writer . toBuffer ( ) ;
@@ -400,11 +400,12 @@ Packet.Question.decode = function(reader) {
400400} ;
401401
402402Packet . Question . encode = function ( question , writer ) {
403+ const ownsWriter = ! writer ;
403404 writer = writer || new Packet . Writer ( ) ;
404405 Packet . Name . encode ( question . name , writer ) ;
405406 writer . write ( question . type , 16 ) ;
406407 writer . write ( question . class , 16 ) ;
407- return writer . toBuffer ( ) ;
408+ return ownsWriter ? writer . toBuffer ( ) : undefined ;
408409} ;
409410
410411/**
@@ -572,6 +573,10 @@ Packet.Name = {
572573 return name . join ( '.' ) ;
573574 } ,
574575 encode : function ( domain , writer ) {
576+ // Only materialize a Buffer when we created the writer; if the caller
577+ // passed one, they own the final toBuffer() and we avoid an O(buffer)
578+ // materialization per name (a big deal once many records share a suffix).
579+ const ownsWriter = ! writer ;
575580 writer = writer || new Packet . Writer ( ) ;
576581 const parts = ( domain || '' ) . split ( '.' ) . filter ( part => ! ! part ) ;
577582 let totalOctets = 1 ; // root terminator
@@ -598,7 +603,7 @@ Packet.Name = {
598603 const suffix = parts . slice ( i ) . join ( '.' ) . toLowerCase ( ) ;
599604 if ( compress && writer . names . has ( suffix ) ) {
600605 writer . write ( 0xC000 | writer . names . get ( suffix ) , 16 ) ;
601- return writer . toBuffer ( ) ;
606+ return ownsWriter ? writer . toBuffer ( ) : undefined ;
602607 }
603608 if ( compress ) {
604609 const byteOffset = writer . byteLength ( ) ;
@@ -610,7 +615,7 @@ Packet.Name = {
610615 }
611616 }
612617 writer . write ( 0 , 8 ) ;
613- return writer . toBuffer ( ) ;
618+ return ownsWriter ? writer . toBuffer ( ) : undefined ;
614619 } ,
615620} ;
616621
@@ -629,10 +634,11 @@ Packet.Resource.A = function(address) {
629634Packet . Resource . A . encode = function ( record , writer ) {
630635 writer = writer || new Packet . Writer ( ) ;
631636 // RDLENGTH is written by Packet.Resource.encode; only emit the rdata here.
637+ // No toBuffer() — the caller owns materialization (avoids O(N) re-walks of
638+ // the message bit-array per record).
632639 record . address . split ( '.' ) . forEach ( function ( part ) {
633640 writer . write ( parseInt ( part , 10 ) , 8 ) ;
634641 } ) ;
635- return writer . toBuffer ( ) ;
636642} ;
637643
638644Packet . Resource . A . decode = function ( reader , length ) {
@@ -665,7 +671,6 @@ Packet.Resource.MX.encode = function(record, writer) {
665671 writer = writer || new Packet . Writer ( ) ;
666672 writer . write ( record . priority , 16 ) ;
667673 Packet . Name . encode ( record . exchange , writer ) ;
668- return writer . toBuffer ( ) ;
669674} ;
670675/**
671676 * [decode description]
@@ -698,7 +703,6 @@ Packet.Resource.AAAA = {
698703 fromIPv6 ( record . address ) . forEach ( function ( part ) {
699704 writer . write ( parseInt ( part , 16 ) , 16 ) ;
700705 } ) ;
701- return writer . toBuffer ( ) ;
702706 } ,
703707} ;
704708/**
@@ -714,7 +718,6 @@ Packet.Resource.NS = {
714718 encode : function ( record , writer ) {
715719 writer = writer || new Packet . Writer ( ) ;
716720 Packet . Name . encode ( record . ns , writer ) ;
717- return writer . toBuffer ( ) ;
718721 } ,
719722} ;
720723/**
@@ -731,7 +734,6 @@ Packet.Resource.CNAME = {
731734 encode : function ( record , writer ) {
732735 writer = writer || new Packet . Writer ( ) ;
733736 Packet . Name . encode ( record . domain , writer ) ;
734- return writer . toBuffer ( ) ;
735737 } ,
736738} ;
737739/**
@@ -784,8 +786,6 @@ Packet.Resource.TXT = {
784786 writer . write ( c , 8 ) ;
785787 } ) ;
786788 } ) ;
787-
788- return writer . toBuffer ( ) ;
789789 } ,
790790} ;
791791/**
@@ -814,7 +814,6 @@ Packet.Resource.SOA = {
814814 writer . write ( record . expiration , 32 ) ;
815815 // RFC 2308 §4: the SOA minimum field is also a TTL; same 31-bit ceiling.
816816 writer . write ( Math . min ( record . minimum >>> 0 , 0x7FFFFFFF ) , 32 ) ;
817- return writer . toBuffer ( ) ;
818817 } ,
819818} ;
820819/**
@@ -836,7 +835,6 @@ Packet.Resource.SRV = {
836835 writer . write ( record . weight , 16 ) ;
837836 writer . write ( record . port , 16 ) ;
838837 Packet . Name . encode ( record . target , writer ) ;
839- return writer . toBuffer ( ) ;
840838 } ,
841839} ;
842840
@@ -921,7 +919,6 @@ Packet.Resource.EDNS.encode = function(record, writer) {
921919 debug ( 'node-dns > unknown EDNS rdata encoder %s(%j)' , encoder , rdata . ednsCode ) ;
922920 }
923921 }
924- return writer . toBuffer ( ) ;
925922} ;
926923
927924Packet . Resource . EDNS . ECS = function ( clientIp ) {
@@ -1024,7 +1021,6 @@ Packet.Resource.CAA = {
10241021 buffer . forEach ( function ( c ) {
10251022 writer . write ( c , 8 ) ;
10261023 } ) ;
1027- return writer . toBuffer ( ) ;
10281024 } ,
10291025 decode : function ( reader , length ) {
10301026 this . flags = reader . read ( 8 ) ;
@@ -1083,7 +1079,6 @@ Packet.Resource.DNSKEY = {
10831079 buffer . forEach ( function ( c ) {
10841080 writer . write ( c , 8 ) ;
10851081 } ) ;
1086- return writer . toBuffer ( ) ;
10871082 } ,
10881083} ;
10891084
0 commit comments