diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java index 358a963df3..c31ce891d6 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java @@ -1103,7 +1103,7 @@ byte[] generateReply(Message query, Socket s) LOG.debug("calling addAnswer"); byte rcode = addAnswer(response, name, type, dclass, 0, flags); if (rcode != Rcode.NOERROR) { - rcode = remoteLookup(response, name); + rcode = remoteLookup(response, name, 0); response.getHeader().setRcode(rcode); } addAdditional(response, flags); @@ -1121,7 +1121,7 @@ byte[] generateReply(Message query, Socket s) /** * Lookup record from upstream DNS servers. */ - private byte remoteLookup(Message response, Name name) { + private byte remoteLookup(Message response, Name name, int iterations) { // Forward lookup to primary DNS servers Record[] answers = getRecords(name, Type.ANY); try { @@ -1131,6 +1131,12 @@ private byte remoteLookup(Message response, Name name) { } else { response.addRecord(r, Section.ANSWER); } + if (r.getType() == Type.CNAME) { + Name cname = ((CNAMERecord) r).getAlias(); + if (iterations < 6) { + remoteLookup(response, cname, iterations + 1); + } + } } } catch (NullPointerException e) { return Rcode.NXDOMAIN; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/test/java/org/apache/hadoop/registry/server/dns/TestRegistryDNS.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/test/java/org/apache/hadoop/registry/server/dns/TestRegistryDNS.java index 7c78161c6a..9c369d0e2a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/test/java/org/apache/hadoop/registry/server/dns/TestRegistryDNS.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/test/java/org/apache/hadoop/registry/server/dns/TestRegistryDNS.java @@ -395,6 +395,30 @@ Record[] assertDNSQuery(String lookup, int type, int numRecs) return recs; } + Record[] assertDNSQueryNotNull(String lookup, int type) + throws IOException { + Name name = Name.fromString(lookup); + Record question = Record.newRecord(name, type, DClass.IN); + Message query = Message.newQuery(question); + OPTRecord optRecord = new OPTRecord(4096, 0, 0, Flags.DO, null); + query.addRecord(optRecord, Section.ADDITIONAL); + byte[] responseBytes = getRegistryDNS().generateReply(query, null); + Message response = new Message(responseBytes); + assertEquals("not successful", Rcode.NOERROR, response.getRcode()); + assertNotNull("Null response", response); + assertEquals("Questions do not match", query.getQuestion(), + response.getQuestion()); + Record[] recs = response.getSectionArray(Section.ANSWER); + boolean found = false; + for (Record r : recs) { + if (r.getType()==Type.A) { + found = true; + } + } + assertTrue("No A records in answer", found); + return recs; + } + @Test public void testDNSKEYRecord() throws Exception { String publicK = @@ -607,6 +631,24 @@ public void testExampleDotCom() throws Exception { Record[] records = getRegistryDNS().getRecords(name, Type.SOA); assertNotNull("example.com exists:", records); } + + @Test + public void testExternalCNAMERecord() throws Exception { + setRegistryDNS(new RegistryDNS("TestRegistry")); + Configuration conf = new Configuration(); + conf.set(RegistryConstants.KEY_DNS_DOMAIN, "hwx.test"); + conf.set(RegistryConstants.KEY_DNS_ZONE_SUBNET, "172.17.0"); + conf.setTimeDuration(RegistryConstants.KEY_DNS_TTL, 30L, TimeUnit.SECONDS); + conf.set(RegistryConstants.KEY_DNS_ZONES_DIR, + getClass().getResource("/").getFile()); + getRegistryDNS().setDomainName(conf); + getRegistryDNS().initializeZones(conf); + + // start assessing whether correct records are available + Record[] recs = + assertDNSQueryNotNull("mail.yahoo.com.", Type.CNAME); + } + public RegistryDNS getRegistryDNS() { return registryDNS; }