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

This commit is contained in:
Billie Rinaldi 2018-01-12 09:21:17 -08:00
parent b278f7b293
commit 4fb1f45f21
2 changed files with 50 additions and 2 deletions

View File

@ -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;

View File

@ -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;
}