Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/jndi/dns/Resolver.java
38924 views
/*1* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.jndi.dns;262728import javax.naming.*;293031/**32* The Resolver class performs DNS client operations in support of DnsContext.33*34* <p> Every DnsName instance passed to or returned from a method of35* this class should be fully-qualified and contain a root label (an36* empty component at position 0).37*38* @author Scott Seligman39*/4041class Resolver {4243private DnsClient dnsClient;44private int timeout; // initial timeout on UDP queries in ms45private int retries; // number of UDP retries464748/*49* Constructs a new Resolver given its servers and timeout parameters.50* Each server is of the form "server[:port]".51* IPv6 literal host names include delimiting brackets.52* There must be at least one server.53* "timeout" is the initial timeout interval (in ms) for UDP queries,54* and "retries" gives the number of retries per server.55*/56Resolver(String[] servers, int timeout, int retries)57throws NamingException {58this.timeout = timeout;59this.retries = retries;60dnsClient = new DnsClient(servers, timeout, retries);61}6263public void close() {64dnsClient.close();65dnsClient = null;66}676869/*70* Queries resource records of a particular class and type for a71* given domain name.72* Useful values of rrclass are ResourceRecord.[Q]CLASS_xxx.73* Useful values of rrtype are ResourceRecord.[Q]TYPE_xxx.74* If recursion is true, recursion is requested on the query.75* If auth is true, only authoritative responses are accepted.76*/77ResourceRecords query(DnsName fqdn, int rrclass, int rrtype,78boolean recursion, boolean auth)79throws NamingException {80return dnsClient.query(fqdn, rrclass, rrtype, recursion, auth);81}8283/*84* Queries all resource records of a zone given its domain name and class.85* If recursion is true, recursion is requested on the query to find86* the name server (and also on the zone transfer, but it won't matter).87*/88ResourceRecords queryZone(DnsName zone, int rrclass, boolean recursion)89throws NamingException {9091DnsClient cl =92new DnsClient(findNameServers(zone, recursion), timeout, retries);93try {94return cl.queryZone(zone, rrclass, recursion);95} finally {96cl.close();97}98}99100/*101* Finds the zone of a given domain name. The method is to look102* for the first SOA record on the path from the given domain to103* the root. This search may be partially bypassed if the zone's104* SOA record is received in the authority section of a response.105* If recursion is true, recursion is requested on any queries.106*/107DnsName findZoneName(DnsName fqdn, int rrclass, boolean recursion)108throws NamingException {109110fqdn = (DnsName) fqdn.clone();111while (fqdn.size() > 1) { // while below root112ResourceRecords rrs = null;113try {114rrs = query(fqdn, rrclass, ResourceRecord.TYPE_SOA,115recursion, false);116} catch (NameNotFoundException e) {117throw e;118} catch (NamingException e) {119// Ignore error and keep searching up the tree.120}121if (rrs != null) {122if (rrs.answer.size() > 0) { // found zone's SOA123return fqdn;124}125// Look for an SOA record giving the zone's top node.126for (int i = 0; i < rrs.authority.size(); i++) {127ResourceRecord rr = rrs.authority.elementAt(i);128if (rr.getType() == ResourceRecord.TYPE_SOA) {129DnsName zone = rr.getName();130if (fqdn.endsWith(zone)) {131return zone;132}133}134}135}136fqdn.remove(fqdn.size() - 1); // one step rootward137}138return fqdn; // no SOA found below root, so139// return root140}141142/*143* Finds a zone's SOA record. Returns null if no SOA is found (in144* which case "zone" is not actually a zone).145* If recursion is true, recursion is requested on the query.146*/147ResourceRecord findSoa(DnsName zone, int rrclass, boolean recursion)148throws NamingException {149150ResourceRecords rrs = query(zone, rrclass, ResourceRecord.TYPE_SOA,151recursion, false);152for (int i = 0; i < rrs.answer.size(); i++) {153ResourceRecord rr = rrs.answer.elementAt(i);154if (rr.getType() == ResourceRecord.TYPE_SOA) {155return rr;156}157}158return null;159}160161/*162* Finds the name servers of a zone. <tt>zone</tt> is a fully-qualified163* domain name at the top of a zone.164* If recursion is true, recursion is requested on the query.165*/166private String[] findNameServers(DnsName zone, boolean recursion)167throws NamingException {168169// %%% As an optimization, could look in authority section of170// findZoneName() response first.171ResourceRecords rrs =172query(zone, ResourceRecord.CLASS_INTERNET, ResourceRecord.TYPE_NS,173recursion, false);174String[] ns = new String[rrs.answer.size()];175for (int i = 0; i < ns.length; i++) {176ResourceRecord rr = rrs.answer.elementAt(i);177if (rr.getType() != ResourceRecord.TYPE_NS) {178throw new CommunicationException("Corrupted DNS message");179}180ns[i] = (String) rr.getRdata();181182// Server name will be passed to InetAddress.getByName(), which183// may not be able to handle a trailing dot.184// assert ns[i].endsWith(".");185ns[i] = ns[i].substring(0, ns[i].length() - 1);186}187return ns;188}189}190191192