1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen// Copyright (c) 2002-2004 Brian Wellington (bwelling@xbill.org) 2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.xbill.DNS; 4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.*; 6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.*; 7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.net.*; 8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The Lookup object issues queries to caching DNS servers. The input consists 11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * of a name, an optional type, and an optional class. Caching is enabled 12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * by default and used when possible to reduce the number of DNS requests. 13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A Resolver, which defaults to an ExtendedResolver initialized with the 14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * resolvers located by the ResolverConfig class, performs the queries. A 15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * search path of domain suffixes is used to resolve relative names, and is 16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * also determined by the ResolverConfig class. 17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A Lookup object may be reused, but should not be used by multiple threads. 19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see Cache 21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see Resolver 22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see ResolverConfig 23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Brian Wellington 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic final class Lookup { 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static Resolver defaultResolver; 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static Name [] defaultSearchPath; 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static Map defaultCaches; 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static int defaultNdots; 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate Resolver resolver; 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate Name [] searchPath; 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate Cache cache; 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate boolean temporary_cache; 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate int credibility; 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate Name name; 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate int type; 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate int dclass; 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate boolean verbose; 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate int iterations; 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate boolean foundAlias; 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate boolean done; 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate boolean doneCurrent; 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate List aliases; 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate Record [] answers; 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate int result; 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate String error; 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate boolean nxdomain; 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate boolean badresponse; 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate String badresponse_error; 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate boolean networkerror; 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate boolean timedout; 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate boolean nametoolong; 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate boolean referral; 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static final Name [] noAliases = new Name[0]; 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** The lookup was successful. */ 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static final int SUCCESSFUL = 0; 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The lookup failed due to a data or server error. Repeating the lookup 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * would not be helpful. 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static final int UNRECOVERABLE = 1; 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The lookup failed due to a network error. Repeating the lookup may be 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * helpful. 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static final int TRY_AGAIN = 2; 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** The host does not exist. */ 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static final int HOST_NOT_FOUND = 3; 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** The host exists, but has no records associated with the queried type. */ 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static final int TYPE_NOT_FOUND = 4; 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static synchronized void 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrefreshDefault() { 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen defaultResolver = new ExtendedResolver(); 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (UnknownHostException e) { 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new RuntimeException("Failed to initialize resolver"); 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen defaultSearchPath = ResolverConfig.getCurrentConfig().searchPath(); 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen defaultCaches = new HashMap(); 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen defaultNdots = ResolverConfig.getCurrentConfig().ndots(); 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenstatic { 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen refreshDefault(); 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Gets the Resolver that will be used as the default by future Lookups. 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The default resolver. 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static synchronized Resolver 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetDefaultResolver() { 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return defaultResolver; 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the default Resolver to be used as the default by future Lookups. 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param resolver The default resolver. 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static synchronized void 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChensetDefaultResolver(Resolver resolver) { 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen defaultResolver = resolver; 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Gets the Cache that will be used as the default for the specified 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * class by future Lookups. 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param dclass The class whose cache is being retrieved. 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The default cache for the specified class. 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static synchronized Cache 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetDefaultCache(int dclass) { 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DClass.check(dclass); 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Cache c = (Cache) defaultCaches.get(Mnemonic.toInteger(dclass)); 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (c == null) { 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen c = new Cache(dclass); 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen defaultCaches.put(Mnemonic.toInteger(dclass), c); 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return c; 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the Cache to be used as the default for the specified class by future 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Lookups. 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param cache The default cache for the specified class. 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param dclass The class whose cache is being set. 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static synchronized void 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChensetDefaultCache(Cache cache, int dclass) { 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DClass.check(dclass); 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen defaultCaches.put(Mnemonic.toInteger(dclass), cache); 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Gets the search path that will be used as the default by future Lookups. 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The default search path. 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static synchronized Name [] 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetDefaultSearchPath() { 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return defaultSearchPath; 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the search path to be used as the default by future Lookups. 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param domains The default search path. 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static synchronized void 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChensetDefaultSearchPath(Name [] domains) { 162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen defaultSearchPath = domains; 163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the search path that will be used as the default by future Lookups. 167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param domains The default search path. 168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws TextParseException A name in the array is not a valid DNS name. 169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static synchronized void 171d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChensetDefaultSearchPath(String [] domains) throws TextParseException { 172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (domains == null) { 173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen defaultSearchPath = null; 174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Name [] newdomains = new Name[domains.length]; 177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int i = 0; i < domains.length; i++) 178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen newdomains[i] = Name.fromString(domains[i], Name.root); 179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen defaultSearchPath = newdomains; 180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate final void 183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenreset() { 184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen iterations = 0; 185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen foundAlias = false; 186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = false; 187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen doneCurrent = false; 188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen aliases = null; 189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen answers = null; 190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = -1; 191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen error = null; 192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen nxdomain = false; 193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen badresponse = false; 194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen badresponse_error = null; 195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen networkerror = false; 196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen timedout = false; 197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen nametoolong = false; 198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen referral = false; 199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (temporary_cache) 200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen cache.clearCache(); 201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Create a Lookup object that will find records of the given name, type, 205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * and class. The lookup will use the default cache, resolver, and search 206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * path, and look for records that are reasonably credible. 207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name The name of the desired records 208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param type The type of the desired records 209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param dclass The class of the desired records 210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalArgumentException The type is a meta type other than ANY. 211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see Cache 212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see Resolver 213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see Credibility 214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see Name 215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see Type 216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see DClass 217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic 219d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenLookup(Name name, int type, int dclass) { 220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Type.check(type); 221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DClass.check(dclass); 222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!Type.isRR(type) && type != Type.ANY) 223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("Cannot query for " + 224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen "meta-types other than ANY"); 225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.name = name; 226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.type = type; 227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.dclass = dclass; 228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (Lookup.class) { 229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.resolver = getDefaultResolver(); 230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.searchPath = getDefaultSearchPath(); 231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.cache = getDefaultCache(dclass); 232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.credibility = Credibility.NORMAL; 234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.verbose = Options.check("verbose"); 235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.result = -1; 236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Create a Lookup object that will find records of the given name and type 240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * in the IN class. 241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name The name of the desired records 242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param type The type of the desired records 243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalArgumentException The type is a meta type other than ANY. 244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see #Lookup(Name,int,int) 245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic 247d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenLookup(Name name, int type) { 248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this(name, type, DClass.IN); 249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Create a Lookup object that will find records of type A at the given name 253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * in the IN class. 254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name The name of the desired records 255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see #Lookup(Name,int,int) 256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic 258d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenLookup(Name name) { 259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this(name, Type.A, DClass.IN); 260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Create a Lookup object that will find records of the given name, type, 264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * and class. 265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name The name of the desired records 266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param type The type of the desired records 267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param dclass The class of the desired records 268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws TextParseException The name is not a valid DNS name 269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalArgumentException The type is a meta type other than ANY. 270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see #Lookup(Name,int,int) 271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic 273d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenLookup(String name, int type, int dclass) throws TextParseException { 274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this(Name.fromString(name), type, dclass); 275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Create a Lookup object that will find records of the given name and type 279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * in the IN class. 280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name The name of the desired records 281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param type The type of the desired records 282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws TextParseException The name is not a valid DNS name 283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalArgumentException The type is a meta type other than ANY. 284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see #Lookup(Name,int,int) 285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic 287d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenLookup(String name, int type) throws TextParseException { 288d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this(Name.fromString(name), type, DClass.IN); 289d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 290d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 291d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 292d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Create a Lookup object that will find records of type A at the given name 293d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * in the IN class. 294d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name The name of the desired records 295d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws TextParseException The name is not a valid DNS name 296d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see #Lookup(Name,int,int) 297d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 298d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic 299d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenLookup(String name) throws TextParseException { 300d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this(Name.fromString(name), Type.A, DClass.IN); 301d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 302d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 303d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 304d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the resolver to use when performing this lookup. This overrides the 305d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * default value. 306d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param resolver The resolver to use. 307d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 308d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic void 309d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChensetResolver(Resolver resolver) { 310d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.resolver = resolver; 311d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 312d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 313d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 314d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the search path to use when performing this lookup. This overrides the 315d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * default value. 316d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param domains An array of names containing the search path. 317d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 318d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic void 319d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChensetSearchPath(Name [] domains) { 320d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.searchPath = domains; 321d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 322d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 323d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 324d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the search path to use when performing this lookup. This overrides the 325d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * default value. 326d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param domains An array of names containing the search path. 327d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws TextParseException A name in the array is not a valid DNS name. 328d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 329d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic void 330d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChensetSearchPath(String [] domains) throws TextParseException { 331d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (domains == null) { 332d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.searchPath = null; 333d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 334d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 335d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Name [] newdomains = new Name[domains.length]; 336d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int i = 0; i < domains.length; i++) 337d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen newdomains[i] = Name.fromString(domains[i], Name.root); 338d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.searchPath = newdomains; 339d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 340d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 341d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 342d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the cache to use when performing this lookup. This overrides the 343d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * default value. If the results of this lookup should not be permanently 344d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * cached, null can be provided here. 345d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param cache The cache to use. 346d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 347d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic void 348d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChensetCache(Cache cache) { 349d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (cache == null) { 350d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.cache = new Cache(dclass); 351d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.temporary_cache = true; 352d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else { 353d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.cache = cache; 354d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.temporary_cache = false; 355d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 356d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 357d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 358d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 359d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets ndots to use when performing this lookup, overriding the default value. 360d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Specifically, this refers to the number of "dots" which, if present in a 361d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * name, indicate that a lookup for the absolute name should be attempted 362d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * before appending any search path elements. 363d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param ndots The ndots value to use, which must be greater than or equal to 364d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 0. 365d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 366d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic void 367d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChensetNdots(int ndots) { 368d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (ndots < 0) 369d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("Illegal ndots value: " + 370d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ndots); 371d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen defaultNdots = ndots; 372d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 373d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 374d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 375d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the minimum credibility level that will be accepted when performing 376d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the lookup. This defaults to Credibility.NORMAL. 377d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param credibility The minimum credibility level. 378d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 379d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic void 380d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChensetCredibility(int credibility) { 381d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.credibility = credibility; 382d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 383d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 384d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate void 385d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenfollow(Name name, Name oldname) { 386d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen foundAlias = true; 387d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen badresponse = false; 388d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen networkerror = false; 389d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen timedout = false; 390d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen nxdomain = false; 391d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen referral = false; 392d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen iterations++; 393d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (iterations >= 6 || name.equals(oldname)) { 394d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = UNRECOVERABLE; 395d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen error = "CNAME loop"; 396d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = true; 397d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 398d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 399d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (aliases == null) 400d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen aliases = new ArrayList(); 401d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen aliases.add(oldname); 402d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen lookup(name); 403d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 404d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 405d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate void 406d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenprocessResponse(Name name, SetResponse response) { 407d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (response.isSuccessful()) { 408d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen RRset [] rrsets = response.answers(); 409d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen List l = new ArrayList(); 410d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Iterator it; 411d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int i; 412d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 413d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (i = 0; i < rrsets.length; i++) { 414d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen it = rrsets[i].rrs(); 415d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen while (it.hasNext()) 416d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen l.add(it.next()); 417d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 418d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 419d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = SUCCESSFUL; 420d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen answers = (Record []) l.toArray(new Record[l.size()]); 421d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = true; 422d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (response.isNXDOMAIN()) { 423d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen nxdomain = true; 424d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen doneCurrent = true; 425d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (iterations > 0) { 426d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = HOST_NOT_FOUND; 427d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = true; 428d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 429d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (response.isNXRRSET()) { 430d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = TYPE_NOT_FOUND; 431d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen answers = null; 432d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = true; 433d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (response.isCNAME()) { 434d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen CNAMERecord cname = response.getCNAME(); 435d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen follow(cname.getTarget(), name); 436d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (response.isDNAME()) { 437d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DNAMERecord dname = response.getDNAME(); 438d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 439d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen follow(name.fromDNAME(dname), name); 440d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } catch (NameTooLongException e) { 441d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = UNRECOVERABLE; 442d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen error = "Invalid DNAME target"; 443d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = true; 444d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 445d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (response.isDelegation()) { 446d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // We shouldn't get a referral. Ignore it. 447d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen referral = true; 448d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 449d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 450d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 451d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate void 452d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenlookup(Name current) { 453d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen SetResponse sr = cache.lookupRecords(current, type, credibility); 454d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (verbose) { 455d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen System.err.println("lookup " + current + " " + 456d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Type.string(type)); 457d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen System.err.println(sr); 458d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 459d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen processResponse(current, sr); 460d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (done || doneCurrent) 461d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 462d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 463d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Record question = Record.newRecord(current, type, dclass); 464d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Message query = Message.newQuery(question); 465d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Message response = null; 466d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 467d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response = resolver.send(query); 468d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 469d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (IOException e) { 470d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // A network error occurred. Press on. 471d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (e instanceof InterruptedIOException) 472d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen timedout = true; 473d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else 474d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen networkerror = true; 475d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 476d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 477d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int rcode = response.getHeader().getRcode(); 478d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (rcode != Rcode.NOERROR && rcode != Rcode.NXDOMAIN) { 479d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // The server we contacted is broken or otherwise unhelpful. 480d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Press on. 481d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen badresponse = true; 482d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen badresponse_error = Rcode.string(rcode); 483d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 484d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 485d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 486d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!query.getQuestion().equals(response.getQuestion())) { 487d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // The answer doesn't match the question. That's not good. 488d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen badresponse = true; 489d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen badresponse_error = "response does not match query"; 490d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 491d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 492d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 493d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sr = cache.addMessage(response); 494d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (sr == null) 495d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sr = cache.lookupRecords(current, type, credibility); 496d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (verbose) { 497d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen System.err.println("queried " + current + " " + 498d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Type.string(type)); 499d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen System.err.println(sr); 500d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 501d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen processResponse(current, sr); 502d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 503d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 504d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate void 505d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenresolve(Name current, Name suffix) { 506d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen doneCurrent = false; 507d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Name tname = null; 508d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (suffix == null) 509d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen tname = current; 510d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else { 511d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 512d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen tname = Name.concatenate(current, suffix); 513d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 514d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (NameTooLongException e) { 515d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen nametoolong = true; 516d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 517d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 518d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 519d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen lookup(tname); 520d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 521d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 522d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 523d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Performs the lookup, using the specified Cache, Resolver, and search path. 524d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The answers, or null if none are found. 525d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 526d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic Record [] 527d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenrun() { 528d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (done) 529d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen reset(); 530d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (name.isAbsolute()) 531d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen resolve(name, null); 532d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (searchPath == null) 533d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen resolve(name, Name.root); 534d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else { 535d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (name.labels() > defaultNdots) 536d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen resolve(name, Name.root); 537d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (done) 538d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return answers; 539d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 540d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int i = 0; i < searchPath.length; i++) { 541d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen resolve(name, searchPath[i]); 542d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (done) 543d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return answers; 544d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (foundAlias) 545d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen break; 546d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 547d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 548d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!done) { 549d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (badresponse) { 550d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = TRY_AGAIN; 551d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen error = badresponse_error; 552d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = true; 553d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (timedout) { 554d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = TRY_AGAIN; 555d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen error = "timed out"; 556d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = true; 557d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (networkerror) { 558d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = TRY_AGAIN; 559d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen error = "network error"; 560d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = true; 561d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (nxdomain) { 562d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = HOST_NOT_FOUND; 563d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = true; 564d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (referral) { 565d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = UNRECOVERABLE; 566d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen error = "referral"; 567d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = true; 568d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (nametoolong) { 569d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = UNRECOVERABLE; 570d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen error = "name too long"; 571d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen done = true; 572d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 573d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 574d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return answers; 575d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 576d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 577d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate void 578d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChencheckDone() { 579d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (done && result != -1) 580d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 581d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen StringBuffer sb = new StringBuffer("Lookup of " + name + " "); 582d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (dclass != DClass.IN) 583d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(DClass.string(dclass) + " "); 584d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(Type.string(type) + " isn't done"); 585d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalStateException(sb.toString()); 586d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 587d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 588d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 589d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the answers from the lookup. 590d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The answers, or null if none are found. 591d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalStateException The lookup has not completed. 592d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 593d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic Record [] 594d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetAnswers() { 595d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen checkDone(); 596d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return answers; 597d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 598d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 599d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 600d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns all known aliases for this name. Whenever a CNAME/DNAME is 601d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * followed, an alias is added to this array. The last element in this 602d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * array will be the owner name for records in the answer, if there are any. 603d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The aliases. 604d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalStateException The lookup has not completed. 605d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 606d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic Name [] 607d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetAliases() { 608d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen checkDone(); 609d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (aliases == null) 610d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return noAliases; 611d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return (Name []) aliases.toArray(new Name[aliases.size()]); 612d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 613d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 614d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 615d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the result code of the lookup. 616d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The result code, which can be SUCCESSFUL, UNRECOVERABLE, TRY_AGAIN, 617d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * HOST_NOT_FOUND, or TYPE_NOT_FOUND. 618d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalStateException The lookup has not completed. 619d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 620d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic int 621d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetResult() { 622d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen checkDone(); 623d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return result; 624d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 625d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 626d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 627d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns an error string describing the result code of this lookup. 628d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return A string, which may either directly correspond the result code 629d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * or be more specific. 630d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalStateException The lookup has not completed. 631d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 632d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic String 633d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetErrorString() { 634d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen checkDone(); 635d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (error != null) 636d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return error; 637d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen switch (result) { 638d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case SUCCESSFUL: return "successful"; 639d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case UNRECOVERABLE: return "unrecoverable error"; 640d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case TRY_AGAIN: return "try again"; 641d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case HOST_NOT_FOUND: return "host not found"; 642d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen case TYPE_NOT_FOUND: return "type not found"; 643d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 644d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalStateException("unknown result"); 645d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 646d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 647d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 648