package DNS::LDNS::Resolver; use 5.008008; use strict; use warnings; use DNS::LDNS ':all'; our $VERSION = '0.52'; sub new { my ($class, %args) = @_; my $file; my $status = &LDNS_STATUS_OK; if ($args{filename}) { unless (open FILE, $args{filename}) { $DNS::LDNS::last_status = &LDNS_STATUS_FILE_ERR; $DNS::LDNS::line_nr = 0; return; } $file = \*FILE; } elsif ($args{file}) { $file = $args{file}; } my $resolver; if ($file) { $resolver = _new_from_file($file, $status); } else { $resolver = _new(); } if ($args{filename}) { close $file; } $DNS::LDNS::last_status = $status; if (!defined $resolver) { return; } return $resolver; } sub dnssec_anchors { my $self = shift; return DNS::LDNS::GC::own($self->_dnssec_anchors, $self); } sub push_dnssec_anchor { my ($self, $rr) = @_; _push_dnssec_anchor($self, my $copy = $rr->clone); DNS::LDNS::GC::own($copy, $self); } sub set_dnssec_anchors { my ($self, $l) = @_; DNS::LDNS::GC::disown(my $old = $self->dnssec_anchors); $self->_set_dnssec_anchors($l); DNS::LDNS::GC::own($l, $self); return $l; } sub domain { my $self = shift; return DNS::LDNS::GC::own($self->_domain, $self); } sub set_domain { my ($self, $dom) = @_; DNS::LDNS::GC::disown(my $old = $self->domain); _set_domain($self, my $copy = $dom->clone); DNS::LDNS::GC::own($copy, $self); } sub nameservers { my $self = shift; my $list = _nameservers($self); for my $r (@$list) { DNS::LDNS::GC::own($r, $self); } return wantarray ? @$list : $list; } sub push_nameserver { my ($self, $n) = @_; my $s = _push_nameserver($self, my $copy = $n->clone); DNS::LDNS::GC::own($copy, $self); $DNS::LDNS::last_status = $s; return $s; } sub pop_nameserver { my $self = shift; return DNS::LDNS::GC::own($self->_pop_nameserver); } sub push_searchlist { my ($self, $rd) = @_; _push_searchlist($self, my $copy = $rd->clone); DNS::LDNS::GC::own($copy, $self); } sub searchlist { my $self = shift; my $list = _searchlist($self); for my $r (@$list) { DNS::LDNS::GC::own($r, $self); } return wantarray ? @$list : $list; } sub timeout { my $self = shift; my $t = _timeout($self); return wantarray ? @$t : $t; } sub rtt { my $self = shift; my $list = _rtt($self); return wantarray ? @$list : $list; } sub set_rtt { my ($self, @rtt) = @_; # FIXME: Validate @rtt, existence, size _set_rtt($self, \@rtt); } sub fetch_valid_domain_keys { my ($self, $domain, $keys) = @_; my $status; my $trusted = _fetch_valid_domain_keys($self, $domain, $keys, $status); $DNS::LDNS::last_status = $status; if (!$trusted) { return; } return DNS::LDNS::GC::own($trusted, $self); } sub fetch_valid_domain_keys_time { my ($self, $domain, $keys, $checktime) = @_; my $status; my $trusted = _fetch_valid_domain_keys_time( $self, $domain, $keys, $checktime, $status); $DNS::LDNS::last_status = $status; if (!$trusted) { return; } return DNS::LDNS::GC::own($trusted, $self); } sub prepare_query_pkt { my ($self, $rdata, $type, $class, $flags) = @_; my $s = &LDNS_STATUS_OK; my $qry = _prepare_query_pkt($self, $rdata, $type, $class, $flags, $s); $DNS::LDNS::last_status = $s; if ($s != LDNS_STATUS_OK) { return; } return $qry; } sub send { my ($self, $rdata, $type, $class, $flags) = @_; my $s = &LDNS_STATUS_OK; my $ans = _send($self, $rdata, $type, $class, $flags, $s); $DNS::LDNS::last_status = $s; if ($s != LDNS_STATUS_OK) { return; } return $ans; } sub send_pkt { my ($self, $qry) = @_; my $s = &LDNS_STATUS_OK; my $ans = _send_pkt($self, $qry, $s); $DNS::LDNS::last_status = $s; if ($s != LDNS_STATUS_OK) { return; } return $ans; } sub verify_trusted { my ($self, $rrset, $rrsigs, $validating_keys) = @_; my $s = _verify_trusted($self, $rrset, $rrsigs, $validating_keys); $DNS::LDNS::last_status = $s; return $s; } sub verify_trusted_time { my ($self, $rrset, $rrsigs, $check_time, $validating_keys) = @_; my $s = _verify_trusted_time($self, $rrset, $rrsigs, $check_time, $validating_keys); $DNS::LDNS::last_status = $s; return $s; } sub DESTROY { DNS::LDNS::GC::free($_[0]); } 1; __END__ =head1 NAME DNS::LDNS::Resolver - DNS resolver =head1 SYNOPSIS use DNS::LDNS ':all' my r = new DNS::LDNS::Resolver(filename => '/my/resolv.conf') my r = new DNS::LDNS::Resolver(file => \*FILE) my r = new DNS::LDNS::Resolver bool = r->dnssec r->set_dnssec(bool) bool = r->dnssec_cd # Resolver sets the CD bit r->set_dnssec_cd(bool) port = r->port r->set_port(port) bool = r->recursive r->set_recursive(bool) bool = r->debug r->set_debug(bool) count = r->retry r->set_retry(count) count = r->retrans r->set_retrans(count) bool = r->fallback # Resolver truncation fallback mechanism r->set_fallback(bool) bool = r->ip6 r->set_ip6(bool) size = r->edns_udp_size r->set_edns_udp_size(size) bool = r->usevc # Use virtual circuit (TCP) r->set_usevc(bool) r->fail r->set_fail r->defnames r->set_defnames r->dnsrch r->set_dnsrch r->igntc r->set_igntc bool = r->random # randomize nameserver before usage r->set_random(bool) rrlist = r->dnssec_anchors # list of trusted DNSSEC anchors r->push_dnssec_anchor(rr) r->set_dnssec_anchors(rrlist) rdata = r->domain # Domain to add to relative queries r->set_domain(rdata) @rdata = r->nameservers count = r->nameserver_count r->push_nameserver(rdata) rdata = r->pop_nameserver r->nameservers_randomize str = r->tsig_keyname r->set_tsig_keyname(str) str = r->tsig_algorithm r->set_tsig_algorithm(str) str = r->tsig_keydata r->set_tsig_keydata(str) count = r->searchlist_count r->push_searchlist(rdata) @rdata = r->searchlist @times = r->rtt # Round trip times r->set_rtt(@rtt) time = r->nameserver_rtt(pos) r->set_nameserver_rtt(pos, time) (sec, usec) = r->timeout r->set_timeout(sec, usec) # DNSSec validation rrlist = r->fetch_valid_domain_keys(domain, keys) rrlist = r->fetch_valid_domain_keys_time(domain, keys, checktime) rrlist = r->validate_domain_ds(domain, keys) rrlist = r->validate_domain_ds_time(domain, keys, checktime) rrlist = r->validate_domain_dnskey(domain, keys) rrlist = r->validate_domain_dnskey_time(domain, keys, checktime) status = r->verify_trusted(rrset, rrsigs, validation_keys) status = r->verify_trusted_time(rrset, rrsigs, checktime, validation_keys) bool = r->trusted_key(keys, trusted_keys) chain = r->build_data_chain(qflags, dataset, pkt, orig_rr) # Query pkt = r->query(rdata, type, class, flags) pkt = r->search(rdata, type, class, flags) query = r->prepare_query_pkt(rdata, type, class, flags) answer = r->send(rdata, type, class, flags) answer = r->send_pkt(query) rrlist = r->get_rr_list_addr_by_name(name, class, flags) rrlist = r->get_rr_list_name_by_addr(addr, class, flags) =head1 SEE ALSO http://www.nlnetlabs.nl/projects/ldns =head1 AUTHOR Erik Pihl Ostlyngen, Eerik.ostlyngen@uninett.noE =head1 COPYRIGHT AND LICENSE Copyright (C) 2013 by UNINETT Norid AS This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.14.2 or, at your option, any later version of Perl 5 you may have available. =cut