[ldns-users] ldns perl wrapper

Erik Østlyngen erik.ostlyngen at uninett.no
Sat May 18 13:39:59 UTC 2013


Hi Henry,

Thanks a lot for for your comments. I agree that creating specialized
constructors for common RRs is a good idea. So far I've focused on only
mapping the C functions and make them available for perl. There are
probably many other higher level methods which could be useful also,
which could be added in pure perl.

I'm not sure that I understand your comments about the gc. Using the
built-in perl gc in the 'naive' way is imo problematic because freeing
each single struct instead of doing a deep free is very cpu and memory
consuming for large zonefiles because it is then necessary to map the
whole structure of rrlists, rrs and rdatas to their own perl object at
them moment the parent object is created (for example when a zone is
read from file). Some of the reason for making a library wrapper rather
than just doing pure perl then falls away. After all the perl wrapper
will have to mimic the whole data structure that the c-library makes for
you. My approach has been to create a perl object of a sub structure
only if and when it is accessed. Another design choise I made is that if
a substruct is accessed, the returned perl-wrapper object references the
original struct rather than making a clone. But if a structure is
_inserted_ as a substructure into an object, a clone is made. I've made
a small comment on this in the LDNS.pm perldoc.

In your example code, you indicate subclassing the RR into RR::SOA, etc.
This is imo a good idea which I have been thinking about
without finding a good way to do it. The problem is that each time an rr
is returned (and a perl object is wrapped around it), I then have to
determine which kind of rr is returned and re-bless the perl object into
the right kind of subclass. I'm not sure that can be done directly with
the xs typemap functionality. But I'm a novice when it comes to perl xs.
If I find a good way to do this, other classes might be subclassed too,
e.g. rrlist -> rrset and rdata -> dname.

Btw. There are some known bugs which are not commented. One of them is
the default values in the constructors which do not work. Parts of the
ldns library has not yet been mapped, for example the *_buffer and
*_wire functions and some of the functions for handling specific key types.

Regards,
Erik Østlyngen


On 05/17/2013 09:27 AM, Henri Asseily wrote:
> Hello Erik, this is looking good. Clearly it's a pure low level API
> (i.e. a "thin" wrapper to the C API), but from there it becomes easy
> to create a more perl-ish API. For example, the creation of an RR
> shouldn't be as involved as:
> 
> my $rr1 = new Net::LDNS::RR( type => LDNS_RR_TYPE_SOA, class =>
> LDNS_RR_CLASS_CH, ttl => 1234, owner => new
> Net::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'myzone.org'), rdata => [ new
> Net::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'hostmaster.myzone.org'), new
> Net::LDNS::RData(LDNS_RDF_TYPE_DNAME, 'master.myzone.org'), new
> Net::LDNS::RData(LDNS_RDF_TYPE_INT32, '2012113030'), new
> Net::LDNS::RData(LDNS_RDF_TYPE_PERIOD, '12345'), new
> Net::LDNS::RData(LDNS_RDF_TYPE_PERIOD, '1827'), new
> Net::LDNS::RData(LDNS_RDF_TYPE_PERIOD, '2345678'), new
> Net::LDNS::RData(LDNS_RDF_TYPE_PERIOD, '87654') ], );
> 
> For starters, I would create a map for standard RR types that would
> know the content (and types) of the rdata array, or create new RR
> type classes. So one would be able to do:
> 
> my $rr1 = new Net::LDNS::RR::SOA( ttl => 1234, owner =>
> 'myzone.org', serial => 2012113030, refresh => 12345, update =>
> 1827, expiry => 2345678, minimum => 87654, );
> 
> with of course default values where it makes sense.
> 
> Again, this can (and should) all be done in pure perl, now that the
> low level interface is there.
> 
> Regarding the garbage collection, you should indeed be leveraging the
> Perl GC. There shouldn't be a concept of an explicit owner in Perl if
> one can avoid it. You shouldn't have to worry about higher-ups
> "owning" via the C API lower level objects (i.e. RR owning RDATAs)
> since the RDATAs will be linked to the RR through the Perl layer
> anyway (RDATAs being array members of RRs). All you should worry
> about is that when destroy'ing the objects that you keep doing what
> you do:
> 
> sub DESTROY { Net::LDNS::GC::free($_[0]); }
> 
> (but see below)
> 
> All the deep_free stuff is useless here, since the Perl GC will call
> DESTROY on every object that is refcounted to zero anyway, so all
> RDATAs for example will be DESTROYed in turn when an RR is destroyed,
> assuming the RDATA object only exists in one RR.
> 
> I think you should be able to simply get totally rid of all your GC
> since XS will add xx_newmortal() in the generated code for your
> object constructors. That ensures that Perl "owns" the generated
> object and manages the refcounts.
> 
> Now there's another thing you can do as well, which should make your
> code cleaner: you can get rid of your "sub DESTROY" in each of the
> Perl packages by putting the DESTROY code in the XS file since it all
> just calls the C destruction code.
> 
> Say you have:
> 
> MODULE = Net::LDNS     PACKAGE = Net::LDNS::RR
> 
> Replace it with:
> 
> MODULE = Net::LDNS  PACKAGE = Net::LDNS::RR  PREFIX = ldnsrr_
> 
> and then you add:
> 
> void ldnsrr_DESTROY(rr) ldns_rr *rr CODE: ldns_rr_free(rr)
> 
> 
> I hope that what I wrote above doesn't confuse more than it helps.
> 
> --- Henri Asseily henri.tel
> 
> "For me, it is far better to grasp the Universe as it really is than
> to persist in delusion, however satisfying and reassuring." —Carl
> Sagan
> 
> On May 13, 2013, at 2:59 PM, "Erik P. Ostlyngen"
> <erik.ostlyngen at uninett.no> wrote:
> 
>> Hi,
>> 
>> I have created a perl xs wrapper for the ldns library which might
>> be useful for other programmers. My motivation for creating another
>> DNS library for perl was that I needed a tool for doing zonefile
>> analysis and dnssec with better performance than Net::DNS (which is
>> otherwise the preferred library).
>> 
>> https://github.com/erikoest/Net-LDNS
>> 
>> Comments are welcome. Please be aware that it is still beta. The 
>> object freeing and reference counting is a bit involved. I wonder
>> if it could have been done in a simpler way, e.g. using the
>> built-in perl gc.
>> 
>> If you find it useful, you may include it in the ldns source
>> package.
>> 
>> Regards, Erik Østlyngen 
>> _______________________________________________ ldns-users mailing
>> list ldns-users at open.nlnetlabs.nl 
>> http://open.nlnetlabs.nl/mailman/listinfo/ldns-users
> 




More information about the ldns-users mailing list