فهرست منبع

YARN-7731. RegistryDNS should handle upstream DNS returning CNAME. Contributed by Eric Yang

Billie Rinaldi 7 سال پیش
والد
کامیت
4fb1f45f21

+ 8 - 2
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/main/java/org/apache/hadoop/registry/server/dns/RegistryDNS.java

@@ -1103,7 +1103,7 @@ public class RegistryDNS extends AbstractService implements DNSOperations,
     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 @@ public class RegistryDNS extends AbstractService implements DNSOperations,
   /**
    * 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 @@ public class RegistryDNS extends AbstractService implements DNSOperations,
         } 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;

+ 42 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-registry/src/test/java/org/apache/hadoop/registry/server/dns/TestRegistryDNS.java

@@ -395,6 +395,30 @@ public class TestRegistryDNS extends Assert {
     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 class TestRegistryDNS extends Assert {
     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;
   }