From 45ad7cbe9ffde523c4469c9c9a94b4880f30786f Mon Sep 17 00:00:00 2001 From: Jon Maron Date: Wed, 13 Apr 2016 18:21:58 -0400 Subject: [PATCH] YARN-4757 simplified reverse lookup zone approach for large networks --- .../hadoop/registry/server/dns/RegistryDNS.java | 167 +++++---------------- .../registry/server/dns/TestRegistryDNS.java | 47 ++++-- 2 files changed, 74 insertions(+), 140 deletions(-) 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 7c2ce0e..7f7e2a2 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 @@ -25,16 +25,11 @@ import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.net.NetUtils; import org.apache.hadoop.registry.client.api.DNSOperations; -import org.apache.hadoop.registry.client.binding.RegistryPathUtils; -import org.apache.hadoop.registry.client.types.AddressTypes; -import org.apache.hadoop.registry.client.types.Endpoint; import org.apache.hadoop.registry.client.types.ServiceRecord; import org.apache.hadoop.registry.client.types.yarn.YarnRegistryAttributes; import org.apache.hadoop.service.AbstractService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.xbill.DNS.AAAARecord; -import org.xbill.DNS.ARecord; import org.xbill.DNS.CNAMERecord; import org.xbill.DNS.DClass; import org.xbill.DNS.DNSKEYRecord; @@ -49,21 +44,17 @@ import org.xbill.DNS.NameTooLongException; import org.xbill.DNS.OPTRecord; import org.xbill.DNS.Opcode; -import org.xbill.DNS.PTRRecord; import org.xbill.DNS.RRSIGRecord; import org.xbill.DNS.RRset; import org.xbill.DNS.Rcode; import org.xbill.DNS.Record; import org.xbill.DNS.Resolver; -import org.xbill.DNS.ReverseMap; import org.xbill.DNS.SOARecord; -import org.xbill.DNS.SRVRecord; import org.xbill.DNS.Section; import org.xbill.DNS.SetResponse; import org.xbill.DNS.SimpleResolver; import org.xbill.DNS.TSIG; import org.xbill.DNS.TSIGRecord; -import org.xbill.DNS.TXTRecord; import org.xbill.DNS.TextParseException; import org.xbill.DNS.Type; import org.xbill.DNS.Zone; @@ -74,12 +65,10 @@ import java.io.FileInputStream; import java.io.IOException; import java.math.BigInteger; -import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; -import java.net.URI; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; @@ -90,19 +79,12 @@ import java.security.PrivateKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPrivateKeySpec; -import java.text.MessageFormat; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; -import java.util.Collections; import java.util.Date; -import java.util.HashSet; import java.util.Iterator; -import java.util.List; -import java.util.Map; import java.util.Properties; -import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -227,7 +209,7 @@ int initializeZones(Configuration conf) throws IOException { Zone registryZone = configureZone(Name.fromString(domainName), conf); zones.put(registryZone.getOrigin(), registryZone); - initializeReverseLookupZones(conf); + initializeReverseLookupZone(conf); return port; } @@ -299,14 +281,12 @@ public boolean accept( * @param conf the Hadoop configuration. * @throws IOException */ - private void initializeReverseLookupZones(Configuration conf) + private void initializeReverseLookupZone(Configuration conf) throws IOException { - List reverserLookupZones = getReverseZoneNames(conf); - for (Name reverserLookupZoneName: reverserLookupZones) { - Zone reverseLookupZone = - configureZone(reverserLookupZoneName, conf); - zones.put(reverseLookupZone.getOrigin(), reverseLookupZone); - } + Name reverseLookupZoneName = getReverseZoneName(conf); + Zone reverseLookupZone = + configureZone(reverseLookupZoneName, conf); + zones.put(reverseLookupZone.getOrigin(), reverseLookupZone); } /** @@ -315,8 +295,8 @@ private void initializeReverseLookupZones(Configuration conf) * @return the list of reverse zone names required based on the configuration * properties. */ - protected List getReverseZoneNames (Configuration conf) { - List names = new ArrayList<>(); + protected Name getReverseZoneName(Configuration conf) { + Name name = null; String zoneSubnet = getZoneSubnet(conf); if (zoneSubnet == null) { LOG.warn("Zone subnet is not configured. Reverse lookups disabled"); @@ -326,17 +306,12 @@ private void initializeReverseLookupZones(Configuration conf) if (mask != null) { // get the range of IPs SubnetUtils utils = new SubnetUtils(zoneSubnet, mask); - // limit the IPs to network addresses - try { - names = getReverseZoneNamesInSubnet(conf, utils); - } catch (TextParseException e) { - LOG.warn("Unable to gather network addresses from netmask/range", e); - } + name = getReverseZoneName(utils, zoneSubnet); } else { - names.add(getReverseZoneName(zoneSubnet)); + name = getReverseZoneName(zoneSubnet); } } - return names; + return name; } /** @@ -362,15 +337,38 @@ private String getZoneSubnet(Configuration conf) { * @return the reverse zone name. */ private Name getReverseZoneName(String networkAddress) { + return getReverseZoneName(null, networkAddress); + } + + /** + * Return the reverse zone name based on the address. + * @param utils subnet utils + * @param networkAddress the network address. + * @return the reverse zone name. + */ + private Name getReverseZoneName(SubnetUtils utils, String networkAddress) { Name reverseZoneName = null; + boolean isLargeNetwork = false; + if (utils != null) { + isLargeNetwork = utils.getInfo().getAddressCount() > 256; + } final String[] bytes = networkAddress.split("\\."); if (bytes.length == 4) { - String reverseLookupZoneName = - String.format("%s.%s.%s.%s", - bytes[2], - bytes[1], - bytes[0], - IN_ADDR_ARPA); + String reverseLookupZoneName = null; + if (isLargeNetwork) { + reverseLookupZoneName = + String.format("%s.%s.%s", + bytes[1], + bytes[0], + IN_ADDR_ARPA); + } else { + reverseLookupZoneName = + String.format("%s.%s.%s.%s", + bytes[2], + bytes[1], + bytes[0], + IN_ADDR_ARPA); + } try { reverseZoneName = Name.fromString(reverseLookupZoneName); } catch (TextParseException e) { @@ -381,91 +379,6 @@ private Name getReverseZoneName(String networkAddress) { } /** - * Returns a list of reverse zone names for all network addresses available - * based on the configuration properties. - * @param conf the configuration. - * @param utils the subnet utilities. - * @return the list of names. - * @throws TextParseException - */ - private List getReverseZoneNamesInSubnet(Configuration conf, - SubnetUtils utils) - throws TextParseException { - List names = new ArrayList<>(); - String[] addresses = utils.getInfo().getAllAddresses(); - InetAddress minIp = getInetAddress(conf, KEY_DNS_ZONE_IP_MIN); - InetAddress maxIp = getInetAddress(conf, KEY_DNS_ZONE_IP_MAX); - for (String address : addresses) { - if (address.endsWith(".0") && isInRange (minIp, maxIp, address)) { - names.add(getReverseZoneName(address)); - } - } - return names; - } - - /** - * Returns a configured address. - * @param conf the configuration. - * @param key the property key for the address value. - * @return - */ - private InetAddress getInetAddress(Configuration conf, String key) { - String address = conf.get(key); - InetAddress ip = null; - if (address != null) { - try { - ip = InetAddress.getByName(address); - } catch (UnknownHostException e) { - LOG.warn("Unable to convert {} to a network address", address); - } - } - return ip; - } - - /** - * Returns indication of whether the IP provided is greater than the min value, - * less than the max value, or both. - * @param minIp the minimum IP value. - * @param maxIp the maximum IP. - * @param address the address to check. - * @return - */ - private boolean isInRange(InetAddress minIp, InetAddress maxIp, - String address) { - boolean inRange = true; - InetAddress ip = null; - try { - ip = InetAddress.getByName(address); - } catch (UnknownHostException e) { - LOG.warn("Unable to convert {} to IP address", address); - } - if (ip != null) { - if (minIp != null) { - inRange &= ipToLong(ip) >= ipToLong(minIp); - } - if (maxIp != null) { - inRange &= ipToLong(ip) < ipToLong(maxIp); - } - } - return inRange; - } - - /** - * Converts an IP address to a long value. - * @param ip the IP address. - * @return the long value. - */ - private long ipToLong(InetAddress ip) { - byte[] octets = ip.getAddress(); - long result = 0; - for (byte octet : octets) { - result <<= 8; - result |= octet & 0xff; - } - return result; - } - - /** * Create the zone and its related zone associated DNS records (NS, SOA) * @param zoneName domain name of the zone * @param conf configuration reference. 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 d6d988d..2aeb4ef 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 @@ -17,7 +17,6 @@ package org.apache.hadoop.registry.server.dns; import org.apache.commons.net.util.Base64; -import org.apache.commons.net.util.SubnetUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.registry.client.api.RegistryConstants; import org.apache.hadoop.registry.client.binding.RegistryUtils; @@ -28,7 +27,6 @@ import org.junit.Test; import org.xbill.DNS.AAAARecord; import org.xbill.DNS.ARecord; -import org.xbill.DNS.Address; import org.xbill.DNS.CNAMERecord; import org.xbill.DNS.DClass; import org.xbill.DNS.DNSKEYRecord; @@ -53,14 +51,12 @@ import java.security.KeyFactory; import java.security.PrivateKey; import java.security.spec.RSAPrivateKeySpec; -import java.util.ArrayList; import java.util.Calendar; import java.util.Date; -import java.util.Iterator; -import java.util.List; import java.util.concurrent.TimeUnit; -import static org.apache.hadoop.registry.client.api.RegistryConstants.*; +import static org.apache.hadoop.registry.client.api.RegistryConstants.KEY_DNS_ZONE_MASK; +import static org.apache.hadoop.registry.client.api.RegistryConstants.KEY_DNS_ZONE_SUBNET; /** * @@ -226,10 +222,12 @@ public void testRecordTTL() throws Exception { ServiceRecord record = marshal.fromBytes("somepath", CONTAINER_RECORD.getBytes()); registryDNS.register( - "/registry/users/root/services/org-apache-slider/test1/components/container-e50-1451931954322-0016-01-000002", record); + "/registry/users/root/services/org-apache-slider/test1/components/container-e50-1451931954322-0016-01-000002", + record); // start assessing whether correct records are available - Record[] recs = assertDNSQuery("ctr-e50-1451931954322-0016-01-000002.hwx.test."); + Record[] recs = assertDNSQuery( + "ctr-e50-1451931954322-0016-01-000002.hwx.test."); assertEquals("wrong result", "172.17.0.19", ((ARecord) recs[0]).getAddress().getHostAddress()); assertEquals("wrong ttl", 30L, recs[0].getTTL()); @@ -255,6 +253,30 @@ public void testReverseLookup() throws Exception { } @Test + public void testReverseLookupInLargeNetwork() throws Exception { + registryDNS = new RegistryDNS("TestRegistry"); + Configuration conf = new Configuration(); + conf.set(RegistryConstants.KEY_DNS_DOMAIN, "hwx.test"); + conf.set(KEY_DNS_ZONE_SUBNET, "172.17.0.0"); + conf.set(KEY_DNS_ZONE_MASK, "255.255.224.0"); + conf.setTimeDuration(RegistryConstants.KEY_DNS_TTL, 30L, TimeUnit.SECONDS); + + registryDNS.setDomainName(conf); + registryDNS.initializeZones(conf); + + ServiceRecord record = marshal.fromBytes("somepath", + CONTAINER_RECORD.getBytes()); + registryDNS.register( + "/registry/users/root/services/org-apache-slider/test1/components/container-e50-1451931954322-0016-01-000002", record); + + // start assessing whether correct records are available + Record[] recs = assertDNSQuery("19.0.17.172.in-addr.arpa.", Type.PTR, 1); + assertEquals("wrong result", + "ctr-e50-1451931954322-0016-01-000002.hwx.test.", + ((PTRRecord) recs[0]).getTarget().toString()); + } + + @Test public void testMissingReverseLookup() throws Exception { ServiceRecord record = marshal.fromBytes("somepath", CONTAINER_RECORD.getBytes()); @@ -389,7 +411,8 @@ public void testNegativeLookup() throws Exception { ServiceRecord record = marshal.fromBytes("somepath", CONTAINER_RECORD.getBytes()); registryDNS.register( - "/registry/users/root/services/org-apache-slider/test1/components/container-e50-1451931954322-0016-01-000002", record); + "/registry/users/root/services/org-apache-slider/test1/components/container-e50-1451931954322-0016-01-000002", + record); // start assessing whether correct records are available Name name = Name.fromString("missing.hwx.test."); @@ -472,11 +495,9 @@ public void testReverseZoneNames() throws Exception { Configuration conf = new Configuration(); conf.set(KEY_DNS_ZONE_SUBNET, "172.26.32.0"); conf.set(KEY_DNS_ZONE_MASK, "255.255.224.0"); - conf.set(KEY_DNS_ZONE_IP_MIN, "172.26.48.0"); - conf.set(KEY_DNS_ZONE_IP_MAX, "172.26.63.253"); - List names = registryDNS.getReverseZoneNames(conf); - assertEquals("wrong number of names", 16, names.size()); + Name name = registryDNS.getReverseZoneName(conf); + assertEquals("wrong name", "26.172.in-addr.arpa.", name.toString()); } } -- 2.5.4 (Apple Git-61)