diff --git a/LICENSES/dnsjava-LICENSE b/LICENSES/dnsjava-LICENSE index 70bae6b9..60bca5d9 100644 --- a/LICENSES/dnsjava-LICENSE +++ b/LICENSES/dnsjava-LICENSE @@ -1,24 +1,30 @@ -Copyright (c) 1998-2011, Brian Wellington. +Copyright (c) 1998-2019, Brian Wellington +Copyright (c) 2005 VeriSign. All rights reserved. +Copyright (c) 2019-2023, dnsjava authors + All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/build.gradle b/build.gradle index 07735ba7..74d54c6f 100644 --- a/build.gradle +++ b/build.gradle @@ -79,6 +79,7 @@ dependencies { implementation 'org.apache.commons:commons-compress:1.28.0' implementation 'com.github.luben:zstd-jni:1.5.6-3' implementation 'org.brotli:dec:0.1.2' + implementation 'dnsjava:dnsjava:3.6.4' implementation files('libs/agent15.jar') implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1" @@ -138,7 +139,7 @@ def spotlessTarget = { String pattern -> fileTree('.') { include pattern // dena/ は対象に含めたい - exclude 'bin/**', 'build/**', '.gradle/**', 'src/main/java/core/org/**', 'denaN/**', 'denaL/**' + exclude 'bin/**', 'build/**', '.gradle/**', 'denaN/**', 'denaL/**' } } diff --git a/src/main/java/core/org/xbill/DNS/A6Record.java b/src/main/java/core/org/xbill/DNS/A6Record.java deleted file mode 100644 index a1c613a8..00000000 --- a/src/main/java/core/org/xbill/DNS/A6Record.java +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.net.*; - -/** - * A6 Record - maps a domain name to an IPv6 address (experimental) - * - * @author Brian Wellington - */ - -public class A6Record extends Record { - -private static final long serialVersionUID = -8815026887337346789L; - -private int prefixBits; -private InetAddress suffix; -private Name prefix; - -A6Record() {} - -Record -getObject() { - return new A6Record(); -} - -/** - * Creates an A6 Record from the given data - * @param prefixBits The number of bits in the address prefix - * @param suffix The address suffix - * @param prefix The name of the prefix - */ -public -A6Record(Name name, int dclass, long ttl, int prefixBits, - InetAddress suffix, Name prefix) -{ - super(name, Type.A6, dclass, ttl); - this.prefixBits = checkU8("prefixBits", prefixBits); - if (suffix != null && Address.familyOf(suffix) != Address.IPv6) - throw new IllegalArgumentException("invalid IPv6 address"); - this.suffix = suffix; - if (prefix != null) - this.prefix = checkName("prefix", prefix); -} - -void -rrFromWire(DNSInput in) throws IOException { - prefixBits = in.readU8(); - int suffixbits = 128 - prefixBits; - int suffixbytes = (suffixbits + 7) / 8; - if (prefixBits < 128) { - byte [] bytes = new byte[16]; - in.readByteArray(bytes, 16 - suffixbytes, suffixbytes); - suffix = InetAddress.getByAddress(bytes); - } - if (prefixBits > 0) - prefix = new Name(in); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - prefixBits = st.getUInt8(); - if (prefixBits > 128) { - throw st.exception("prefix bits must be [0..128]"); - } else if (prefixBits < 128) { - String s = st.getString(); - try { - suffix = Address.getByAddress(s, Address.IPv6); - } - catch (UnknownHostException e) { - throw st.exception("invalid IPv6 address: " + s); - } - } - if (prefixBits > 0) - prefix = st.getName(origin); -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(prefixBits); - if (suffix != null) { - sb.append(" "); - sb.append(suffix.getHostAddress()); - } - if (prefix != null) { - sb.append(" "); - sb.append(prefix); - } - return sb.toString(); -} - -/** Returns the number of bits in the prefix */ -public int -getPrefixBits() { - return prefixBits; -} - -/** Returns the address suffix */ -public InetAddress -getSuffix() { - return suffix; -} - -/** Returns the address prefix */ -public Name -getPrefix() { - return prefix; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU8(prefixBits); - if (suffix != null) { - int suffixbits = 128 - prefixBits; - int suffixbytes = (suffixbits + 7) / 8; - byte [] data = suffix.getAddress(); - out.writeByteArray(data, 16 - suffixbytes, suffixbytes); - } - if (prefix != null) - prefix.toWire(out, null, canonical); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/AAAARecord.java b/src/main/java/core/org/xbill/DNS/AAAARecord.java deleted file mode 100644 index 20ed912a..00000000 --- a/src/main/java/core/org/xbill/DNS/AAAARecord.java +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.net.*; - -/** - * IPv6 Address Record - maps a domain name to an IPv6 address - * - * @author Brian Wellington - */ - -public class AAAARecord extends Record { - -private static final long serialVersionUID = -4588601512069748050L; - -private byte [] address; - -AAAARecord() {} - -Record -getObject() { - return new AAAARecord(); -} - -/** - * Creates an AAAA Record from the given data - * @param address The address suffix - */ -public -AAAARecord(Name name, int dclass, long ttl, InetAddress address) { - super(name, Type.AAAA, dclass, ttl); - if (Address.familyOf(address) != Address.IPv6) - throw new IllegalArgumentException("invalid IPv6 address"); - this.address = address.getAddress(); -} - -void -rrFromWire(DNSInput in) throws IOException { - address = in.readByteArray(16); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - address = st.getAddressBytes(Address.IPv6); -} - -/** Converts rdata to a String */ -String -rrToString() { - InetAddress addr; - try { - addr = InetAddress.getByAddress(null, address); - } catch (UnknownHostException e) { - return null; - } - if (addr.getAddress().length == 4) { - // Deal with Java's broken handling of mapped IPv4 addresses. - StringBuffer sb = new StringBuffer("0:0:0:0:0:ffff:"); - int high = ((address[12] & 0xFF) << 8) + (address[13] & 0xFF); - int low = ((address[14] & 0xFF) << 8) + (address[15] & 0xFF); - sb.append(Integer.toHexString(high)); - sb.append(':'); - sb.append(Integer.toHexString(low)); - return sb.toString(); - } - return addr.getHostAddress(); -} - -/** Returns the address */ -public InetAddress -getAddress() { - try { - if (name == null) - return InetAddress.getByAddress(address); - else - return InetAddress.getByAddress(name.toString(), - address); - } catch (UnknownHostException e) { - return null; - } -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeByteArray(address); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/AFSDBRecord.java b/src/main/java/core/org/xbill/DNS/AFSDBRecord.java deleted file mode 100644 index 4814faab..00000000 --- a/src/main/java/core/org/xbill/DNS/AFSDBRecord.java +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * AFS Data Base Record - maps a domain name to the name of an AFS cell - * database server. - * - * - * @author Brian Wellington - */ - -public class AFSDBRecord extends U16NameBase { - -private static final long serialVersionUID = 3034379930729102437L; - -AFSDBRecord() {} - -Record -getObject() { - return new AFSDBRecord(); -} - -/** - * Creates an AFSDB Record from the given data. - * @param subtype Indicates the type of service provided by the host. - * @param host The host providing the service. - */ -public -AFSDBRecord(Name name, int dclass, long ttl, int subtype, Name host) { - super(name, Type.AFSDB, dclass, ttl, subtype, "subtype", host, "host"); -} - -/** Gets the subtype indicating the service provided by the host. */ -public int -getSubtype() { - return getU16Field(); -} - -/** Gets the host providing service for the domain. */ -public Name -getHost() { - return getNameField(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/APLRecord.java b/src/main/java/core/org/xbill/DNS/APLRecord.java deleted file mode 100644 index 5940da23..00000000 --- a/src/main/java/core/org/xbill/DNS/APLRecord.java +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.net.*; -import java.util.*; -import org.xbill.DNS.utils.*; - -/** - * APL - Address Prefix List. See RFC 3123. - * - * @author Brian Wellington - */ - -/* - * Note: this currently uses the same constants as the Address class; - * this could change if more constants are defined for APL records. - */ - -public class APLRecord extends Record { - -public static class Element { - public final int family; - public final boolean negative; - public final int prefixLength; - public final Object address; - - private - Element(int family, boolean negative, Object address, int prefixLength) - { - this.family = family; - this.negative = negative; - this.address = address; - this.prefixLength = prefixLength; - if (!validatePrefixLength(family, prefixLength)) { - throw new IllegalArgumentException("invalid prefix " + - "length"); - } - } - - /** - * Creates an APL element corresponding to an IPv4 or IPv6 prefix. - * @param negative Indicates if this prefix is a negation. - * @param address The IPv4 or IPv6 address. - * @param prefixLength The length of this prefix, in bits. - * @throws IllegalArgumentException The prefix length is invalid. - */ - public - Element(boolean negative, InetAddress address, int prefixLength) { - this(Address.familyOf(address), negative, address, - prefixLength); - } - - public String - toString() { - StringBuffer sb = new StringBuffer(); - if (negative) - sb.append("!"); - sb.append(family); - sb.append(":"); - if (family == Address.IPv4 || family == Address.IPv6) - sb.append(((InetAddress) address).getHostAddress()); - else - sb.append(base16.toString((byte []) address)); - sb.append("/"); - sb.append(prefixLength); - return sb.toString(); - } - - public boolean - equals(Object arg) { - if (arg == null || !(arg instanceof Element)) - return false; - Element elt = (Element) arg; - return (family == elt.family && - negative == elt.negative && - prefixLength == elt.prefixLength && - address.equals(elt.address)); - } - - public int - hashCode() { - return address.hashCode() + prefixLength + (negative ? 1 : 0); - } -} - -private static final long serialVersionUID = -1348173791712935864L; - -private List elements; - -APLRecord() {} - -Record -getObject() { - return new APLRecord(); -} - -private static boolean -validatePrefixLength(int family, int prefixLength) { - if (prefixLength < 0 || prefixLength >= 256) - return false; - if ((family == Address.IPv4 && prefixLength > 32) || - (family == Address.IPv6 && prefixLength > 128)) - return false; - return true; -} - -/** - * Creates an APL Record from the given data. - * @param elements The list of APL elements. - */ -public -APLRecord(Name name, int dclass, long ttl, List elements) { - super(name, Type.APL, dclass, ttl); - this.elements = new ArrayList(elements.size()); - for (Iterator it = elements.iterator(); it.hasNext(); ) { - Object o = it.next(); - if (!(o instanceof Element)) { - throw new IllegalArgumentException("illegal element"); - } - Element element = (Element) o; - if (element.family != Address.IPv4 && - element.family != Address.IPv6) - { - throw new IllegalArgumentException("unknown family"); - } - this.elements.add(element); - - } -} - -private static byte [] -parseAddress(byte [] in, int length) throws WireParseException { - if (in.length > length) - throw new WireParseException("invalid address length"); - if (in.length == length) - return in; - byte [] out = new byte[length]; - System.arraycopy(in, 0, out, 0, in.length); - return out; -} - -void -rrFromWire(DNSInput in) throws IOException { - elements = new ArrayList(1); - while (in.remaining() != 0) { - int family = in.readU16(); - int prefix = in.readU8(); - int length = in.readU8(); - boolean negative = (length & 0x80) != 0; - length &= ~0x80; - - byte [] data = in.readByteArray(length); - Element element; - if (!validatePrefixLength(family, prefix)) { - throw new WireParseException("invalid prefix length"); - } - - if (family == Address.IPv4 || family == Address.IPv6) { - data = parseAddress(data, - Address.addressLength(family)); - InetAddress addr = InetAddress.getByAddress(data); - element = new Element(negative, addr, prefix); - } else { - element = new Element(family, negative, data, prefix); - } - elements.add(element); - - } -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - elements = new ArrayList(1); - while (true) { - Tokenizer.Token t = st.get(); - if (!t.isString()) - break; - - boolean negative = false; - int family = 0; - int prefix = 0; - - String s = t.value; - int start = 0; - if (s.startsWith("!")) { - negative = true; - start = 1; - } - int colon = s.indexOf(':', start); - if (colon < 0) - throw st.exception("invalid address prefix element"); - int slash = s.indexOf('/', colon); - if (slash < 0) - throw st.exception("invalid address prefix element"); - - String familyString = s.substring(start, colon); - String addressString = s.substring(colon + 1, slash); - String prefixString = s.substring(slash + 1); - - try { - family = Integer.parseInt(familyString); - } - catch (NumberFormatException e) { - throw st.exception("invalid family"); - } - if (family != Address.IPv4 && family != Address.IPv6) - throw st.exception("unknown family"); - - try { - prefix = Integer.parseInt(prefixString); - } - catch (NumberFormatException e) { - throw st.exception("invalid prefix length"); - } - - if (!validatePrefixLength(family, prefix)) { - throw st.exception("invalid prefix length"); - } - - byte [] bytes = Address.toByteArray(addressString, family); - if (bytes == null) - throw st.exception("invalid IP address " + - addressString); - - InetAddress address = InetAddress.getByAddress(bytes); - elements.add(new Element(negative, address, prefix)); - } - st.unget(); -} - -String -rrToString() { - StringBuffer sb = new StringBuffer(); - for (Iterator it = elements.iterator(); it.hasNext(); ) { - Element element = (Element) it.next(); - sb.append(element); - if (it.hasNext()) - sb.append(" "); - } - return sb.toString(); -} - -/** Returns the list of APL elements. */ -public List -getElements() { - return elements; -} - -private static int -addressLength(byte [] addr) { - for (int i = addr.length - 1; i >= 0; i--) { - if (addr[i] != 0) - return i + 1; - } - return 0; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - for (Iterator it = elements.iterator(); it.hasNext(); ) { - Element element = (Element) it.next(); - int length = 0; - byte [] data; - if (element.family == Address.IPv4 || - element.family == Address.IPv6) - { - InetAddress addr = (InetAddress) element.address; - data = addr.getAddress(); - length = addressLength(data); - } else { - data = (byte []) element.address; - length = data.length; - } - int wlength = length; - if (element.negative) { - wlength |= 0x80; - } - out.writeU16(element.family); - out.writeU8(element.prefixLength); - out.writeU8(wlength); - out.writeByteArray(data, 0, length); - } -} - -} diff --git a/src/main/java/core/org/xbill/DNS/ARecord.java b/src/main/java/core/org/xbill/DNS/ARecord.java deleted file mode 100644 index 63d17304..00000000 --- a/src/main/java/core/org/xbill/DNS/ARecord.java +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.net.*; -import java.io.*; - -/** - * Address Record - maps a domain name to an Internet address - * - * @author Brian Wellington - */ - -public class ARecord extends Record { - -private static final long serialVersionUID = -2172609200849142323L; - -private int addr; - -ARecord() {} - -Record -getObject() { - return new ARecord(); -} - -private static final int -fromArray(byte [] array) { - return (((array[0] & 0xFF) << 24) | - ((array[1] & 0xFF) << 16) | - ((array[2] & 0xFF) << 8) | - (array[3] & 0xFF)); -} - -private static final byte [] -toArray(int addr) { - byte [] bytes = new byte[4]; - bytes[0] = (byte) ((addr >>> 24) & 0xFF); - bytes[1] = (byte) ((addr >>> 16) & 0xFF); - bytes[2] = (byte) ((addr >>> 8) & 0xFF); - bytes[3] = (byte) (addr & 0xFF); - return bytes; -} - -/** - * Creates an A Record from the given data - * @param address The address that the name refers to - */ -public -ARecord(Name name, int dclass, long ttl, InetAddress address) { - super(name, Type.A, dclass, ttl); - if (Address.familyOf(address) != Address.IPv4) - throw new IllegalArgumentException("invalid IPv4 address"); - addr = fromArray(address.getAddress()); -} - -void -rrFromWire(DNSInput in) throws IOException { - addr = fromArray(in.readByteArray(4)); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - addr = fromArray(st.getAddressBytes(Address.IPv4)); -} - -/** Converts rdata to a String */ -String -rrToString() { - return (Address.toDottedQuad(toArray(addr))); -} - -/** Returns the Internet address */ -public InetAddress -getAddress() { - try { - if (name == null) - return InetAddress.getByAddress(toArray(addr)); - else - return InetAddress.getByAddress(name.toString(), - toArray(addr)); - } catch (UnknownHostException e) { - return null; - } -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU32(((long)addr) & 0xFFFFFFFFL); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Address.java b/src/main/java/core/org/xbill/DNS/Address.java deleted file mode 100644 index c706beb4..00000000 --- a/src/main/java/core/org/xbill/DNS/Address.java +++ /dev/null @@ -1,422 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.net.*; -import java.net.Inet6Address; - -/** - * Routines dealing with IP addresses. Includes functions similar to - * those in the java.net.InetAddress class. - * - * @author Brian Wellington - */ - -public final class Address { - -public static final int IPv4 = 1; -public static final int IPv6 = 2; - -private -Address() {} - -private static byte [] -parseV4(String s) { - int numDigits; - int currentOctet; - byte [] values = new byte[4]; - int currentValue; - int length = s.length(); - - currentOctet = 0; - currentValue = 0; - numDigits = 0; - for (int i = 0; i < length; i++) { - char c = s.charAt(i); - if (c >= '0' && c <= '9') { - /* Can't have more than 3 digits per octet. */ - if (numDigits == 3) - return null; - /* Octets shouldn't start with 0, unless they are 0. */ - if (numDigits > 0 && currentValue == 0) - return null; - numDigits++; - currentValue *= 10; - currentValue += (c - '0'); - /* 255 is the maximum value for an octet. */ - if (currentValue > 255) - return null; - } else if (c == '.') { - /* Can't have more than 3 dots. */ - if (currentOctet == 3) - return null; - /* Two consecutive dots are bad. */ - if (numDigits == 0) - return null; - values[currentOctet++] = (byte) currentValue; - currentValue = 0; - numDigits = 0; - } else - return null; - } - /* Must have 4 octets. */ - if (currentOctet != 3) - return null; - /* The fourth octet can't be empty. */ - if (numDigits == 0) - return null; - values[currentOctet] = (byte) currentValue; - return values; -} - -private static byte [] -parseV6(String s) { - int range = -1; - byte [] data = new byte[16]; - - String [] tokens = s.split(":", -1); - - int first = 0; - int last = tokens.length - 1; - - if (tokens[0].length() == 0) { - // If the first two tokens are empty, it means the string - // started with ::, which is fine. If only the first is - // empty, the string started with :, which is bad. - if (last - first > 0 && tokens[1].length() == 0) - first++; - else - return null; - } - - if (tokens[last].length() == 0) { - // If the last two tokens are empty, it means the string - // ended with ::, which is fine. If only the last is - // empty, the string ended with :, which is bad. - if (last - first > 0 && tokens[last - 1].length() == 0) - last--; - else - return null; - } - - if (last - first + 1 > 8) - return null; - - int i, j; - for (i = first, j = 0; i <= last; i++) { - if (tokens[i].length() == 0) { - if (range >= 0) - return null; - range = j; - continue; - } - - if (tokens[i].indexOf('.') >= 0) { - // An IPv4 address must be the last component - if (i < last) - return null; - // There can't have been more than 6 components. - if (i > 6) - return null; - byte [] v4addr = Address.toByteArray(tokens[i], IPv4); - if (v4addr == null) - return null; - for (int k = 0; k < 4; k++) - data[j++] = v4addr[k]; - break; - } - - try { - for (int k = 0; k < tokens[i].length(); k++) { - char c = tokens[i].charAt(k); - if (Character.digit(c, 16) < 0) - return null; - } - int x = Integer.parseInt(tokens[i], 16); - if (x > 0xFFFF || x < 0) - return null; - data[j++] = (byte)(x >>> 8); - data[j++] = (byte)(x & 0xFF); - } - catch (NumberFormatException e) { - return null; - } - } - - if (j < 16 && range < 0) - return null; - - if (range >= 0) { - int empty = 16 - j; - System.arraycopy(data, range, data, range + empty, j - range); - for (i = range; i < range + empty; i++) - data[i] = 0; - } - - return data; -} - -/** - * Convert a string containing an IP address to an array of 4 or 16 integers. - * @param s The address, in text format. - * @param family The address family. - * @return The address - */ -public static int [] -toArray(String s, int family) { - byte [] byteArray = toByteArray(s, family); - if (byteArray == null) - return null; - int [] intArray = new int[byteArray.length]; - for (int i = 0; i < byteArray.length; i++) - intArray[i] = byteArray[i] & 0xFF; - return intArray; -} - -/** - * Convert a string containing an IPv4 address to an array of 4 integers. - * @param s The address, in text format. - * @return The address - */ -public static int [] -toArray(String s) { - return toArray(s, IPv4); -} - -/** - * Convert a string containing an IP address to an array of 4 or 16 bytes. - * @param s The address, in text format. - * @param family The address family. - * @return The address - */ -public static byte [] -toByteArray(String s, int family) { - if (family == IPv4) - return parseV4(s); - else if (family == IPv6) - return parseV6(s); - else - throw new IllegalArgumentException("unknown address family"); -} - -/** - * Determines if a string contains a valid IP address. - * @param s The string - * @return Whether the string contains a valid IP address - */ -public static boolean -isDottedQuad(String s) { - byte [] address = Address.toByteArray(s, IPv4); - return (address != null); -} - -/** - * Converts a byte array containing an IPv4 address into a dotted quad string. - * @param addr The array - * @return The string representation - */ -public static String -toDottedQuad(byte [] addr) { - return ((addr[0] & 0xFF) + "." + (addr[1] & 0xFF) + "." + - (addr[2] & 0xFF) + "." + (addr[3] & 0xFF)); -} - -/** - * Converts an int array containing an IPv4 address into a dotted quad string. - * @param addr The array - * @return The string representation - */ -public static String -toDottedQuad(int [] addr) { - return (addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3]); -} - -private static Record [] -lookupHostName(String name, boolean all) throws UnknownHostException { - try { - Lookup lookup = new Lookup(name, Type.A); - Record [] a = lookup.run(); - if (a == null) { - if (lookup.getResult() == Lookup.TYPE_NOT_FOUND) { - Record [] aaaa = new Lookup(name, Type.AAAA).run(); - if (aaaa != null) - return aaaa; - } - throw new UnknownHostException("unknown host"); - } - if (! all) - return a; - Record [] aaaa = new Lookup(name, Type.AAAA).run(); - if (aaaa == null) - return a; - Record [] merged = new Record[a.length + aaaa.length]; - System.arraycopy(a, 0, merged, 0, a.length); - System.arraycopy(aaaa, 0, merged, a.length, aaaa.length); - return merged; - } - catch (TextParseException e) { - throw new UnknownHostException("invalid name"); - } -} - -private static InetAddress -addrFromRecord(String name, Record r) throws UnknownHostException { - InetAddress addr; - if (r instanceof ARecord) { - addr = ((ARecord)r).getAddress(); - } else { - addr = ((AAAARecord)r).getAddress(); - } - return InetAddress.getByAddress(name, addr.getAddress()); -} - -/** - * Determines the IP address of a host - * @param name The hostname to look up - * @return The first matching IP address - * @exception UnknownHostException The hostname does not have any addresses - */ -public static InetAddress -getByName(String name) throws UnknownHostException { - try { - return getByAddress(name); - } catch (UnknownHostException e) { - Record [] records = lookupHostName(name, false); - return addrFromRecord(name, records[0]); - } -} - -/** - * Determines all IP address of a host - * @param name The hostname to look up - * @return All matching IP addresses - * @exception UnknownHostException The hostname does not have any addresses - */ -public static InetAddress [] -getAllByName(String name) throws UnknownHostException { - try { - InetAddress addr = getByAddress(name); - return new InetAddress[] {addr}; - } catch (UnknownHostException e) { - Record [] records = lookupHostName(name, true); - InetAddress [] addrs = new InetAddress[records.length]; - for (int i = 0; i < records.length; i++) - addrs[i] = addrFromRecord(name, records[i]); - return addrs; - } -} - -/** - * Converts an address from its string representation to an IP address. - * The address can be either IPv4 or IPv6. - * @param addr The address, in string form - * @return The IP addresses - * @exception UnknownHostException The address is not a valid IP address. - */ -public static InetAddress -getByAddress(String addr) throws UnknownHostException { - byte [] bytes; - bytes = toByteArray(addr, IPv4); - if (bytes != null) - return InetAddress.getByAddress(addr, bytes); - bytes = toByteArray(addr, IPv6); - if (bytes != null) - return InetAddress.getByAddress(addr, bytes); - throw new UnknownHostException("Invalid address: " + addr); -} - -/** - * Converts an address from its string representation to an IP address in - * a particular family. - * @param addr The address, in string form - * @param family The address family, either IPv4 or IPv6. - * @return The IP addresses - * @exception UnknownHostException The address is not a valid IP address in - * the specified address family. - */ -public static InetAddress -getByAddress(String addr, int family) throws UnknownHostException { - if (family != IPv4 && family != IPv6) - throw new IllegalArgumentException("unknown address family"); - byte [] bytes; - bytes = toByteArray(addr, family); - if (bytes != null) - return InetAddress.getByAddress(addr, bytes); - throw new UnknownHostException("Invalid address: " + addr); -} - -/** - * Determines the hostname for an address - * @param addr The address to look up - * @return The associated host name - * @exception UnknownHostException There is no hostname for the address - */ -public static String -getHostName(InetAddress addr) throws UnknownHostException { - Name name = ReverseMap.fromAddress(addr); - Record [] records = new Lookup(name, Type.PTR).run(); - if (records == null) - throw new UnknownHostException("unknown address"); - PTRRecord ptr = (PTRRecord) records[0]; - return ptr.getTarget().toString(); -} - -/** - * Returns the family of an InetAddress. - * @param address The supplied address. - * @return The family, either IPv4 or IPv6. - */ -public static int -familyOf(InetAddress address) { - if (address instanceof Inet4Address) - return IPv4; - if (address instanceof Inet6Address) - return IPv6; - throw new IllegalArgumentException("unknown address family"); -} - -/** - * Returns the length of an address in a particular family. - * @param family The address family, either IPv4 or IPv6. - * @return The length of addresses in that family. - */ -public static int -addressLength(int family) { - if (family == IPv4) - return 4; - if (family == IPv6) - return 16; - throw new IllegalArgumentException("unknown address family"); -} - -/** - * Truncates an address to the specified number of bits. For example, - * truncating the address 10.1.2.3 to 8 bits would yield 10.0.0.0. - * @param address The source address - * @param maskLength The number of bits to truncate the address to. - */ -public static InetAddress -truncate(InetAddress address, int maskLength) -{ - int family = familyOf(address); - int maxMaskLength = addressLength(family) * 8; - if (maskLength < 0 || maskLength > maxMaskLength) - throw new IllegalArgumentException("invalid mask length"); - if (maskLength == maxMaskLength) - return address; - byte [] bytes = address.getAddress(); - for (int i = maskLength / 8 + 1; i < bytes.length; i++) - bytes[i] = 0; - int maskBits = maskLength % 8; - int bitmask = 0; - for (int i = 0; i < maskBits; i++) - bitmask |= (1 << (7 - i)); - bytes[maskLength / 8] &= bitmask; - try { - return InetAddress.getByAddress(bytes); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("invalid address"); - } -} - -} diff --git a/src/main/java/core/org/xbill/DNS/CAARecord.java b/src/main/java/core/org/xbill/DNS/CAARecord.java deleted file mode 100644 index d5553ec5..00000000 --- a/src/main/java/core/org/xbill/DNS/CAARecord.java +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import org.xbill.DNS.utils.*; - -/** - * Certification Authority Authorization - * - * @author Brian Wellington - */ - -public class CAARecord extends Record { - -private static final long serialVersionUID = 8544304287274216443L; - -public static class Flags { - private Flags() {} - - public static final int IssuerCritical = 128; -} - -private int flags; -private byte [] tag; -private byte [] value; - -CAARecord() {} - -Record -getObject() { - return new CAARecord(); -} - -/** - * Creates an CAA Record from the given data. - * @param flags The flags. - * @param tag The tag. - * @param value The value. - */ -public -CAARecord(Name name, int dclass, long ttl, int flags, String tag, String value) -{ - super(name, Type.CAA, dclass, ttl); - this.flags = checkU8("flags", flags); - try { - this.tag = byteArrayFromString(tag); - this.value = byteArrayFromString(value); - } - catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } -} - -void -rrFromWire(DNSInput in) throws IOException { - flags = in.readU8(); - tag = in.readCountedString(); - value = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - flags = st.getUInt8(); - try { - tag = byteArrayFromString(st.getString()); - value = byteArrayFromString(st.getString()); - } - catch (TextParseException e) { - throw st.exception(e.getMessage()); - } -} - -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(flags); - sb.append(" "); - sb.append(byteArrayToString(tag, false)); - sb.append(" "); - sb.append(byteArrayToString(value, true)); - return sb.toString(); -} - -/** Returns the flags. */ -public int -getFlags() { - return flags; -} - -/** Returns the tag. */ -public String -getTag() { - return byteArrayToString(tag, false); -} - -/** Returns the value */ -public String -getValue() { - return byteArrayToString(value, false); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU8(flags); - out.writeCountedString(tag); - out.writeByteArray(value); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/CERTRecord.java b/src/main/java/core/org/xbill/DNS/CERTRecord.java deleted file mode 100644 index 39bcef3f..00000000 --- a/src/main/java/core/org/xbill/DNS/CERTRecord.java +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import org.xbill.DNS.utils.*; - -/** - * Certificate Record - Stores a certificate associated with a name. The - * certificate might also be associated with a KEYRecord. - * @see KEYRecord - * - * @author Brian Wellington - */ - -public class CERTRecord extends Record { - -public static class CertificateType { - /** Certificate type identifiers. See RFC 4398 for more detail. */ - - private CertificateType() {} - - /** PKIX (X.509v3) */ - public static final int PKIX = 1; - - /** Simple Public Key Infrastructure */ - public static final int SPKI = 2; - - /** Pretty Good Privacy */ - public static final int PGP = 3; - - /** URL of an X.509 data object */ - public static final int IPKIX = 4; - - /** URL of an SPKI certificate */ - public static final int ISPKI = 5; - - /** Fingerprint and URL of an OpenPGP packet */ - public static final int IPGP = 6; - - /** Attribute Certificate */ - public static final int ACPKIX = 7; - - /** URL of an Attribute Certificate */ - public static final int IACPKIX = 8; - - /** Certificate format defined by URI */ - public static final int URI = 253; - - /** Certificate format defined by OID */ - public static final int OID = 254; - - private static Mnemonic types = new Mnemonic("Certificate type", - Mnemonic.CASE_UPPER); - - static { - types.setMaximum(0xFFFF); - types.setNumericAllowed(true); - - types.add(PKIX, "PKIX"); - types.add(SPKI, "SPKI"); - types.add(PGP, "PGP"); - types.add(PKIX, "IPKIX"); - types.add(SPKI, "ISPKI"); - types.add(PGP, "IPGP"); - types.add(PGP, "ACPKIX"); - types.add(PGP, "IACPKIX"); - types.add(URI, "URI"); - types.add(OID, "OID"); - } - - /** - * Converts a certificate type into its textual representation - */ - public static String - string(int type) { - return types.getText(type); - } - - /** - * Converts a textual representation of an certificate type into its - * numeric code. Integers in the range 0..65535 are also accepted. - * @param s The textual representation of the algorithm - * @return The algorithm code, or -1 on error. - */ - public static int - value(String s) { - return types.getValue(s); - } -} - -/** PKIX (X.509v3) */ -public static final int PKIX = CertificateType.PKIX; - -/** Simple Public Key Infrastructure */ -public static final int SPKI = CertificateType.SPKI; - -/** Pretty Good Privacy */ -public static final int PGP = CertificateType.PGP; - -/** Certificate format defined by URI */ -public static final int URI = CertificateType.URI; - -/** Certificate format defined by IOD */ -public static final int OID = CertificateType.OID; - -private static final long serialVersionUID = 4763014646517016835L; - -private int certType, keyTag; -private int alg; -private byte [] cert; - -CERTRecord() {} - -Record -getObject() { - return new CERTRecord(); -} - -/** - * Creates a CERT Record from the given data - * @param certType The type of certificate (see constants) - * @param keyTag The ID of the associated KEYRecord, if present - * @param alg The algorithm of the associated KEYRecord, if present - * @param cert Binary data representing the certificate - */ -public -CERTRecord(Name name, int dclass, long ttl, int certType, int keyTag, - int alg, byte [] cert) -{ - super(name, Type.CERT, dclass, ttl); - this.certType = checkU16("certType", certType); - this.keyTag = checkU16("keyTag", keyTag); - this.alg = checkU8("alg", alg); - this.cert = cert; -} - -void -rrFromWire(DNSInput in) throws IOException { - certType = in.readU16(); - keyTag = in.readU16(); - alg = in.readU8(); - cert = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - String certTypeString = st.getString(); - certType = CertificateType.value(certTypeString); - if (certType < 0) - throw st.exception("Invalid certificate type: " + - certTypeString); - keyTag = st.getUInt16(); - String algString = st.getString(); - alg = DNSSEC.Algorithm.value(algString); - if (alg < 0) - throw st.exception("Invalid algorithm: " + algString); - cert = st.getBase64(); -} - -/** - * Converts rdata to a String - */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append (certType); - sb.append (" "); - sb.append (keyTag); - sb.append (" "); - sb.append (alg); - if (cert != null) { - if (Options.check("multiline")) { - sb.append(" (\n"); - sb.append(base64.formatString(cert, 64, "\t", true)); - } else { - sb.append(" "); - sb.append(base64.toString(cert)); - } - } - return sb.toString(); -} - -/** - * Returns the type of certificate - */ -public int -getCertType() { - return certType; -} - -/** - * Returns the ID of the associated KEYRecord, if present - */ -public int -getKeyTag() { - return keyTag; -} - -/** - * Returns the algorithm of the associated KEYRecord, if present - */ -public int -getAlgorithm() { - return alg; -} - -/** - * Returns the binary representation of the certificate - */ -public byte [] -getCert() { - return cert; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(certType); - out.writeU16(keyTag); - out.writeU8(alg); - out.writeByteArray(cert); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/CNAMERecord.java b/src/main/java/core/org/xbill/DNS/CNAMERecord.java deleted file mode 100644 index 8db9453e..00000000 --- a/src/main/java/core/org/xbill/DNS/CNAMERecord.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * CNAME Record - maps an alias to its real name - * - * @author Brian Wellington - */ - -public class CNAMERecord extends SingleCompressedNameBase { - -private static final long serialVersionUID = -4020373886892538580L; - -CNAMERecord() {} - -Record -getObject() { - return new CNAMERecord(); -} - -/** - * Creates a new CNAMERecord with the given data - * @param alias The name to which the CNAME alias points - */ -public -CNAMERecord(Name name, int dclass, long ttl, Name alias) { - super(name, Type.CNAME, dclass, ttl, alias, "alias"); -} - -/** - * Gets the target of the CNAME Record - */ -public Name -getTarget() { - return getSingleName(); -} - -/** Gets the alias specified by the CNAME Record */ -public Name -getAlias() { - return getSingleName(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Cache.java b/src/main/java/core/org/xbill/DNS/Cache.java deleted file mode 100644 index 5497f453..00000000 --- a/src/main/java/core/org/xbill/DNS/Cache.java +++ /dev/null @@ -1,846 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; - -/** - * A cache of DNS records. The cache obeys TTLs, so items are purged after - * their validity period is complete. Negative answers are cached, to - * avoid repeated failed DNS queries. The credibility of each RRset is - * maintained, so that more credible records replace less credible records, - * and lookups can specify the minimum credibility of data they are requesting. - * @see RRset - * @see Credibility - * - * @author Brian Wellington - */ - -public class Cache { - -private interface Element { - public boolean expired(); - public int compareCredibility(int cred); - public int getType(); -} - -private static int -limitExpire(long ttl, long maxttl) { - if (maxttl >= 0 && maxttl < ttl) - ttl = maxttl; - long expire = (System.currentTimeMillis() / 1000) + ttl; - if (expire < 0 || expire > Integer.MAX_VALUE) - return Integer.MAX_VALUE; - return (int)expire; -} - -private static class CacheRRset extends RRset implements Element { - private static final long serialVersionUID = 5971755205903597024L; - - int credibility; - int expire; - - public - CacheRRset(Record rec, int cred, long maxttl) { - super(); - this.credibility = cred; - this.expire = limitExpire(rec.getTTL(), maxttl); - addRR(rec); - } - - public - CacheRRset(RRset rrset, int cred, long maxttl) { - super(rrset); - this.credibility = cred; - this.expire = limitExpire(rrset.getTTL(), maxttl); - } - - public final boolean - expired() { - int now = (int)(System.currentTimeMillis() / 1000); - return (now >= expire); - } - - public final int - compareCredibility(int cred) { - return credibility - cred; - } - - public String - toString() { - StringBuffer sb = new StringBuffer(); - sb.append(super.toString()); - sb.append(" cl = "); - sb.append(credibility); - return sb.toString(); - } -} - -private static class NegativeElement implements Element { - int type; - Name name; - int credibility; - int expire; - - public - NegativeElement(Name name, int type, SOARecord soa, int cred, - long maxttl) - { - this.name = name; - this.type = type; - long cttl = 0; - if (soa != null) - cttl = soa.getMinimum(); - this.credibility = cred; - this.expire = limitExpire(cttl, maxttl); - } - - public int - getType() { - return type; - } - - public final boolean - expired() { - int now = (int)(System.currentTimeMillis() / 1000); - return (now >= expire); - } - - public final int - compareCredibility(int cred) { - return credibility - cred; - } - - public String - toString() { - StringBuffer sb = new StringBuffer(); - if (type == 0) - sb.append("NXDOMAIN " + name); - else - sb.append("NXRRSET " + name + " " + Type.string(type)); - sb.append(" cl = "); - sb.append(credibility); - return sb.toString(); - } -} - -private static class CacheMap extends LinkedHashMap { - private int maxsize = -1; - - CacheMap(int maxsize) { - super(16, (float) 0.75, true); - this.maxsize = maxsize; - } - - int - getMaxSize() { - return maxsize; - } - - void - setMaxSize(int maxsize) { - /* - * Note that this doesn't shrink the size of the map if - * the maximum size is lowered, but it should shrink as - * entries expire. - */ - this.maxsize = maxsize; - } - - protected boolean removeEldestEntry(Map.Entry eldest) { - return maxsize >= 0 && size() > maxsize; - } -} - -private CacheMap data; -private int maxncache = -1; -private int maxcache = -1; -private int dclass; - -private static final int defaultMaxEntries = 50000; - -/** - * Creates an empty Cache - * - * @param dclass The DNS class of this cache - * @see DClass - */ -public -Cache(int dclass) { - this.dclass = dclass; - data = new CacheMap(defaultMaxEntries); -} - -/** - * Creates an empty Cache for class IN. - * @see DClass - */ -public -Cache() { - this(DClass.IN); -} - -/** - * Creates a Cache which initially contains all records in the specified file. - */ -public -Cache(String file) throws IOException { - data = new CacheMap(defaultMaxEntries); - Master m = new Master(file); - Record record; - while ((record = m.nextRecord()) != null) - addRecord(record, Credibility.HINT, m); -} - -private synchronized Object -exactName(Name name) { - return data.get(name); -} - -private synchronized void -removeName(Name name) { - data.remove(name); -} - -private synchronized Element [] -allElements(Object types) { - if (types instanceof List) { - List typelist = (List) types; - int size = typelist.size(); - return (Element []) typelist.toArray(new Element[size]); - } else { - Element set = (Element) types; - return new Element[] {set}; - } -} - -private synchronized Element -oneElement(Name name, Object types, int type, int minCred) { - Element found = null; - - if (type == Type.ANY) - throw new IllegalArgumentException("oneElement(ANY)"); - if (types instanceof List) { - List list = (List) types; - for (int i = 0; i < list.size(); i++) { - Element set = (Element) list.get(i); - if (set.getType() == type) { - found = set; - break; - } - } - } else { - Element set = (Element) types; - if (set.getType() == type) - found = set; - } - if (found == null) - return null; - if (found.expired()) { - removeElement(name, type); - return null; - } - if (found.compareCredibility(minCred) < 0) - return null; - return found; -} - -private synchronized Element -findElement(Name name, int type, int minCred) { - Object types = exactName(name); - if (types == null) - return null; - return oneElement(name, types, type, minCred); -} - -private synchronized void -addElement(Name name, Element element) { - Object types = data.get(name); - if (types == null) { - data.put(name, element); - return; - } - int type = element.getType(); - if (types instanceof List) { - List list = (List) types; - for (int i = 0; i < list.size(); i++) { - Element elt = (Element) list.get(i); - if (elt.getType() == type) { - list.set(i, element); - return; - } - } - list.add(element); - } else { - Element elt = (Element) types; - if (elt.getType() == type) - data.put(name, element); - else { - LinkedList list = new LinkedList(); - list.add(elt); - list.add(element); - data.put(name, list); - } - } -} - -private synchronized void -removeElement(Name name, int type) { - Object types = data.get(name); - if (types == null) { - return; - } - if (types instanceof List) { - List list = (List) types; - for (int i = 0; i < list.size(); i++) { - Element elt = (Element) list.get(i); - if (elt.getType() == type) { - list.remove(i); - if (list.size() == 0) - data.remove(name); - return; - } - } - } else { - Element elt = (Element) types; - if (elt.getType() != type) - return; - data.remove(name); - } -} - -/** Empties the Cache. */ -public synchronized void -clearCache() { - data.clear(); -} - -/** - * Adds a record to the Cache. - * @param r The record to be added - * @param cred The credibility of the record - * @param o The source of the record (this could be a Message, for example) - * @see Record - */ -public synchronized void -addRecord(Record r, int cred, Object o) { - Name name = r.getName(); - int type = r.getRRsetType(); - if (!Type.isRR(type)) - return; - Element element = findElement(name, type, cred); - if (element == null) { - CacheRRset crrset = new CacheRRset(r, cred, maxcache); - addRRset(crrset, cred); - } else if (element.compareCredibility(cred) == 0) { - if (element instanceof CacheRRset) { - CacheRRset crrset = (CacheRRset) element; - crrset.addRR(r); - } - } -} - -/** - * Adds an RRset to the Cache. - * @param rrset The RRset to be added - * @param cred The credibility of these records - * @see RRset - */ -public synchronized void -addRRset(RRset rrset, int cred) { - long ttl = rrset.getTTL(); - Name name = rrset.getName(); - int type = rrset.getType(); - Element element = findElement(name, type, 0); - if (ttl == 0) { - if (element != null && element.compareCredibility(cred) <= 0) - removeElement(name, type); - } else { - if (element != null && element.compareCredibility(cred) <= 0) - element = null; - if (element == null) { - CacheRRset crrset; - if (rrset instanceof CacheRRset) - crrset = (CacheRRset) rrset; - else - crrset = new CacheRRset(rrset, cred, maxcache); - addElement(name, crrset); - } - } -} - -/** - * Adds a negative entry to the Cache. - * @param name The name of the negative entry - * @param type The type of the negative entry - * @param soa The SOA record to add to the negative cache entry, or null. - * The negative cache ttl is derived from the SOA. - * @param cred The credibility of the negative entry - */ -public synchronized void -addNegative(Name name, int type, SOARecord soa, int cred) { - long ttl = 0; - if (soa != null) - ttl = soa.getTTL(); - Element element = findElement(name, type, 0); - if (ttl == 0) { - if (element != null && element.compareCredibility(cred) <= 0) - removeElement(name, type); - } else { - if (element != null && element.compareCredibility(cred) <= 0) - element = null; - if (element == null) - addElement(name, new NegativeElement(name, type, - soa, cred, - maxncache)); - } -} - -/** - * Finds all matching sets or something that causes the lookup to stop. - */ -protected synchronized SetResponse -lookup(Name name, int type, int minCred) { - int labels; - int tlabels; - Element element; - Name tname; - Object types; - SetResponse sr; - - labels = name.labels(); - - for (tlabels = labels; tlabels >= 1; tlabels--) { - boolean isRoot = (tlabels == 1); - boolean isExact = (tlabels == labels); - - if (isRoot) - tname = Name.root; - else if (isExact) - tname = name; - else - tname = new Name(name, labels - tlabels); - - types = data.get(tname); - if (types == null) - continue; - - /* - * If this is the name, look for the actual type or a CNAME - * (unless it's an ANY query, where we return everything). - * Otherwise, look for a DNAME. - */ - if (isExact && type == Type.ANY) { - sr = new SetResponse(SetResponse.SUCCESSFUL); - Element [] elements = allElements(types); - int added = 0; - for (int i = 0; i < elements.length; i++) { - element = elements[i]; - if (element.expired()) { - removeElement(tname, element.getType()); - continue; - } - if (!(element instanceof CacheRRset)) - continue; - if (element.compareCredibility(minCred) < 0) - continue; - sr.addRRset((CacheRRset)element); - added++; - } - /* There were positive entries */ - if (added > 0) - return sr; - } else if (isExact) { - element = oneElement(tname, types, type, minCred); - if (element != null && - element instanceof CacheRRset) - { - sr = new SetResponse(SetResponse.SUCCESSFUL); - sr.addRRset((CacheRRset) element); - return sr; - } else if (element != null) { - sr = new SetResponse(SetResponse.NXRRSET); - return sr; - } - - element = oneElement(tname, types, Type.CNAME, minCred); - if (element != null && - element instanceof CacheRRset) - { - return new SetResponse(SetResponse.CNAME, - (CacheRRset) element); - } - } else { - element = oneElement(tname, types, Type.DNAME, minCred); - if (element != null && - element instanceof CacheRRset) - { - return new SetResponse(SetResponse.DNAME, - (CacheRRset) element); - } - } - - /* Look for an NS */ - element = oneElement(tname, types, Type.NS, minCred); - if (element != null && element instanceof CacheRRset) - return new SetResponse(SetResponse.DELEGATION, - (CacheRRset) element); - - /* Check for the special NXDOMAIN element. */ - if (isExact) { - element = oneElement(tname, types, 0, minCred); - if (element != null) - return SetResponse.ofType(SetResponse.NXDOMAIN); - } - - } - return SetResponse.ofType(SetResponse.UNKNOWN); -} - -/** - * Looks up Records in the Cache. This follows CNAMEs and handles negatively - * cached data. - * @param name The name to look up - * @param type The type to look up - * @param minCred The minimum acceptable credibility - * @return A SetResponse object - * @see SetResponse - * @see Credibility - */ -public SetResponse -lookupRecords(Name name, int type, int minCred) { - return lookup(name, type, minCred); -} - -private RRset [] -findRecords(Name name, int type, int minCred) { - SetResponse cr = lookupRecords(name, type, minCred); - if (cr.isSuccessful()) - return cr.answers(); - else - return null; -} - -/** - * Looks up credible Records in the Cache (a wrapper around lookupRecords). - * Unlike lookupRecords, this given no indication of why failure occurred. - * @param name The name to look up - * @param type The type to look up - * @return An array of RRsets, or null - * @see Credibility - */ -public RRset [] -findRecords(Name name, int type) { - return findRecords(name, type, Credibility.NORMAL); -} - -/** - * Looks up Records in the Cache (a wrapper around lookupRecords). Unlike - * lookupRecords, this given no indication of why failure occurred. - * @param name The name to look up - * @param type The type to look up - * @return An array of RRsets, or null - * @see Credibility - */ -public RRset [] -findAnyRecords(Name name, int type) { - return findRecords(name, type, Credibility.GLUE); -} - -private final int -getCred(int section, boolean isAuth) { - if (section == Section.ANSWER) { - if (isAuth) - return Credibility.AUTH_ANSWER; - else - return Credibility.NONAUTH_ANSWER; - } else if (section == Section.AUTHORITY) { - if (isAuth) - return Credibility.AUTH_AUTHORITY; - else - return Credibility.NONAUTH_AUTHORITY; - } else if (section == Section.ADDITIONAL) { - return Credibility.ADDITIONAL; - } else - throw new IllegalArgumentException("getCred: invalid section"); -} - -private static void -markAdditional(RRset rrset, Set names) { - Record first = rrset.first(); - if (first.getAdditionalName() == null) - return; - - Iterator it = rrset.rrs(); - while (it.hasNext()) { - Record r = (Record) it.next(); - Name name = r.getAdditionalName(); - if (name != null) - names.add(name); - } -} - -/** - * Adds all data from a Message into the Cache. Each record is added with - * the appropriate credibility, and negative answers are cached as such. - * @param in The Message to be added - * @return A SetResponse that reflects what would be returned from a cache - * lookup, or null if nothing useful could be cached from the message. - * @see Message - */ -public SetResponse -addMessage(Message in) { - boolean isAuth = in.getHeader().getFlag(Flags.AA); - Record question = in.getQuestion(); - Name qname; - Name curname; - int qtype; - int qclass; - int cred; - int rcode = in.getHeader().getRcode(); - boolean completed = false; - RRset [] answers, auth, addl; - SetResponse response = null; - boolean verbose = Options.check("verbosecache"); - HashSet additionalNames; - - if ((rcode != Rcode.NOERROR && rcode != Rcode.NXDOMAIN) || - question == null) - return null; - - qname = question.getName(); - qtype = question.getType(); - qclass = question.getDClass(); - - curname = qname; - - additionalNames = new HashSet(); - - answers = in.getSectionRRsets(Section.ANSWER); - for (int i = 0; i < answers.length; i++) { - if (answers[i].getDClass() != qclass) - continue; - int type = answers[i].getType(); - Name name = answers[i].getName(); - cred = getCred(Section.ANSWER, isAuth); - if ((type == qtype || qtype == Type.ANY) && - name.equals(curname)) - { - addRRset(answers[i], cred); - completed = true; - if (curname == qname) { - if (response == null) - response = new SetResponse( - SetResponse.SUCCESSFUL); - response.addRRset(answers[i]); - } - markAdditional(answers[i], additionalNames); - } else if (type == Type.CNAME && name.equals(curname)) { - CNAMERecord cname; - addRRset(answers[i], cred); - if (curname == qname) - response = new SetResponse(SetResponse.CNAME, - answers[i]); - cname = (CNAMERecord) answers[i].first(); - curname = cname.getTarget(); - } else if (type == Type.DNAME && curname.subdomain(name)) { - DNAMERecord dname; - addRRset(answers[i], cred); - if (curname == qname) - response = new SetResponse(SetResponse.DNAME, - answers[i]); - dname = (DNAMERecord) answers[i].first(); - try { - curname = curname.fromDNAME(dname); - } - catch (NameTooLongException e) { - break; - } - } - } - - auth = in.getSectionRRsets(Section.AUTHORITY); - RRset soa = null, ns = null; - for (int i = 0; i < auth.length; i++) { - if (auth[i].getType() == Type.SOA && - curname.subdomain(auth[i].getName())) - soa = auth[i]; - else if (auth[i].getType() == Type.NS && - curname.subdomain(auth[i].getName())) - ns = auth[i]; - } - if (!completed) { - /* This is a negative response or a referral. */ - int cachetype = (rcode == Rcode.NXDOMAIN) ? 0 : qtype; - if (rcode == Rcode.NXDOMAIN || soa != null || ns == null) { - /* Negative response */ - cred = getCred(Section.AUTHORITY, isAuth); - SOARecord soarec = null; - if (soa != null) - soarec = (SOARecord) soa.first(); - addNegative(curname, cachetype, soarec, cred); - if (response == null) { - int responseType; - if (rcode == Rcode.NXDOMAIN) - responseType = SetResponse.NXDOMAIN; - else - responseType = SetResponse.NXRRSET; - response = SetResponse.ofType(responseType); - } - /* DNSSEC records are not cached. */ - } else { - /* Referral response */ - cred = getCred(Section.AUTHORITY, isAuth); - addRRset(ns, cred); - markAdditional(ns, additionalNames); - if (response == null) - response = new SetResponse( - SetResponse.DELEGATION, - ns); - } - } else if (rcode == Rcode.NOERROR && ns != null) { - /* Cache the NS set from a positive response. */ - cred = getCred(Section.AUTHORITY, isAuth); - addRRset(ns, cred); - markAdditional(ns, additionalNames); - } - - addl = in.getSectionRRsets(Section.ADDITIONAL); - for (int i = 0; i < addl.length; i++) { - int type = addl[i].getType(); - if (type != Type.A && type != Type.AAAA && type != Type.A6) - continue; - Name name = addl[i].getName(); - if (!additionalNames.contains(name)) - continue; - cred = getCred(Section.ADDITIONAL, isAuth); - addRRset(addl[i], cred); - } - if (verbose) - System.out.println("addMessage: " + response); - return (response); -} - -/** - * Flushes an RRset from the cache - * @param name The name of the records to be flushed - * @param type The type of the records to be flushed - * @see RRset - */ -public void -flushSet(Name name, int type) { - removeElement(name, type); -} - -/** - * Flushes all RRsets with a given name from the cache - * @param name The name of the records to be flushed - * @see RRset - */ -public void -flushName(Name name) { - removeName(name); -} - -/** - * Sets the maximum length of time that a negative response will be stored - * in this Cache. A negative value disables this feature (that is, sets - * no limit). - */ -public void -setMaxNCache(int seconds) { - maxncache = seconds; -} - -/** - * Gets the maximum length of time that a negative response will be stored - * in this Cache. A negative value indicates no limit. - */ -public int -getMaxNCache() { - return maxncache; -} - -/** - * Sets the maximum length of time that records will be stored in this - * Cache. A negative value disables this feature (that is, sets no limit). - */ -public void -setMaxCache(int seconds) { - maxcache = seconds; -} - -/** - * Gets the maximum length of time that records will be stored - * in this Cache. A negative value indicates no limit. - */ -public int -getMaxCache() { - return maxcache; -} - -/** - * Gets the current number of entries in the Cache, where an entry consists - * of all records with a specific Name. - */ -public int -getSize() { - return data.size(); -} - -/** - * Gets the maximum number of entries in the Cache, where an entry consists - * of all records with a specific Name. A negative value is treated as an - * infinite limit. - */ -public int -getMaxEntries() { - return data.getMaxSize(); -} - -/** - * Sets the maximum number of entries in the Cache, where an entry consists - * of all records with a specific Name. A negative value is treated as an - * infinite limit. - * - * Note that setting this to a value lower than the current number - * of entries will not cause the Cache to shrink immediately. - * - * The default maximum number of entries is 50000. - * - * @param entries The maximum number of entries in the Cache. - */ -public void -setMaxEntries(int entries) { - data.setMaxSize(entries); -} - -/** - * Returns the DNS class of this cache. - */ -public int -getDClass() { - return dclass; -} - -/** - * Returns the contents of the Cache as a string. - */ -public String -toString() { - StringBuffer sb = new StringBuffer(); - synchronized (this) { - Iterator it = data.values().iterator(); - while (it.hasNext()) { - Element [] elements = allElements(it.next()); - for (int i = 0; i < elements.length; i++) { - sb.append(elements[i]); - sb.append("\n"); - } - } - } - return sb.toString(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Client.java b/src/main/java/core/org/xbill/DNS/Client.java deleted file mode 100644 index 238b99b8..00000000 --- a/src/main/java/core/org/xbill/DNS/Client.java +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2005 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.net.*; -import java.nio.channels.*; -import org.xbill.DNS.utils.hexdump; - -class Client { - -protected long endTime; -protected SelectionKey key; - -/** - * Packet logger, if available. - */ -private static PacketLogger packetLogger = null; - -protected -Client(SelectableChannel channel, long endTime) throws IOException { - boolean done = false; - Selector selector = null; - this.endTime = endTime; - try { - selector = Selector.open(); - channel.configureBlocking(false); - key = channel.register(selector, SelectionKey.OP_READ); - done = true; - } - finally { - if (!done && selector != null) - selector.close(); - if (!done) - channel.close(); - } -} - -static protected void -blockUntil(SelectionKey key, long endTime) throws IOException { - long timeout = endTime - System.currentTimeMillis(); - int nkeys = 0; - if (timeout > 0) - nkeys = key.selector().select(timeout); - else if (timeout == 0) - nkeys = key.selector().selectNow(); - if (nkeys == 0) - throw new SocketTimeoutException(); -} - -static protected void -verboseLog(String prefix, SocketAddress local, SocketAddress remote, - byte [] data) -{ - if (Options.check("verbosemsg")) - System.err.println(hexdump.dump(prefix, data)); - if (packetLogger != null) - packetLogger.log(prefix, local, remote, data); -} - -void -cleanup() throws IOException { - key.selector().close(); - key.channel().close(); -} - -static void setPacketLogger(PacketLogger logger) -{ - packetLogger = logger; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/ClientSubnetOption.java b/src/main/java/core/org/xbill/DNS/ClientSubnetOption.java deleted file mode 100644 index 9a9252af..00000000 --- a/src/main/java/core/org/xbill/DNS/ClientSubnetOption.java +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.net.*; -import java.util.regex.*; - -/** - * The Client Subnet EDNS Option, defined in - * http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-00 - * ("Client subnet in DNS requests"). - * - * The option is used to convey information about the IP address of the - * originating client, so that an authoritative server can make decisions - * based on this address, rather than the address of the intermediate - * caching name server. - * - * The option is transmitted as part of an OPTRecord in the additional section - * of a DNS message, as defined by RFC 2671 (EDNS0). - * - * The wire format of the option contains a 2-byte length field (1 for IPv4, 2 - * for IPv6), a 1-byte source netmask, a 1-byte scope netmask, and an address - * truncated to the source netmask length (where the final octet is padded with - * bits set to 0) - * - * - * @see OPTRecord - * - * @author Brian Wellington - * @author Ming Zhou <mizhou@bnivideo.com>, Beaumaris Networks - */ -public class ClientSubnetOption extends EDNSOption { - -private static final long serialVersionUID = -3868158449890266347L; - -private int family; -private int sourceNetmask; -private int scopeNetmask; -private InetAddress address; - -ClientSubnetOption() { - super(EDNSOption.Code.CLIENT_SUBNET); -} - -private static int -checkMaskLength(String field, int family, int val) { - int max = Address.addressLength(family) * 8; - if (val < 0 || val > max) - throw new IllegalArgumentException("\"" + field + "\" " + val + - " must be in the range " + - "[0.." + max + "]"); - return val; -} - -/** - * Construct a Client Subnet option. Note that the number of significant bits - * in the address must not be greater than the supplied source netmask. There - * may also be issues related to Java's handling of mapped addresses - * @param sourceNetmask The length of the netmask pertaining to the query. - * In replies, it mirrors the same value as in the requests. - * @param scopeNetmask The length of the netmask pertaining to the reply. - * In requests, it MUST be set to 0. In responses, this may or may not match - * the source netmask. - * @param address The address of the client. - */ -public -ClientSubnetOption(int sourceNetmask, int scopeNetmask, InetAddress address) { - super(EDNSOption.Code.CLIENT_SUBNET); - - this.family = Address.familyOf(address); - this.sourceNetmask = checkMaskLength("source netmask", this.family, - sourceNetmask); - this.scopeNetmask = checkMaskLength("scope netmask", this.family, - scopeNetmask); - this.address = Address.truncate(address, sourceNetmask); - - if (!address.equals(this.address)) - throw new IllegalArgumentException("source netmask is not " + - "valid for address"); -} - -/** - * Construct a Client Subnet option with scope netmask set to 0. - * @param sourceNetmask The length of the netmask pertaining to the query. - * In replies, it mirrors the same value as in the requests. - * @param address The address of the client. - * @see ClientSubnetOption - */ -public -ClientSubnetOption(int sourceNetmask, InetAddress address) { - this(sourceNetmask, 0, address); -} - -/** - * Returns the family of the network address. This will be either IPv4 (1) - * or IPv6 (2). - */ -public int -getFamily() { - return family; -} - -/** Returns the source netmask. */ -public int -getSourceNetmask() { - return sourceNetmask; -} - -/** Returns the scope netmask. */ -public int -getScopeNetmask() { - return scopeNetmask; -} - -/** Returns the IP address of the client. */ -public InetAddress -getAddress() { - return address; -} - -void -optionFromWire(DNSInput in) throws WireParseException { - family = in.readU16(); - if (family != Address.IPv4 && family != Address.IPv6) - throw new WireParseException("unknown address family"); - sourceNetmask = in.readU8(); - if (sourceNetmask > Address.addressLength(family) * 8) - throw new WireParseException("invalid source netmask"); - scopeNetmask = in.readU8(); - if (scopeNetmask > Address.addressLength(family) * 8) - throw new WireParseException("invalid scope netmask"); - - // Read the truncated address - byte [] addr = in.readByteArray(); - if (addr.length != (sourceNetmask + 7) / 8) - throw new WireParseException("invalid address"); - - // Convert it to a full length address. - byte [] fulladdr = new byte[Address.addressLength(family)]; - System.arraycopy(addr, 0, fulladdr, 0, addr.length); - - try { - address = InetAddress.getByAddress(fulladdr); - } catch (UnknownHostException e) { - throw new WireParseException("invalid address", e); - } - - InetAddress tmp = Address.truncate(address, sourceNetmask); - if (!tmp.equals(address)) - throw new WireParseException("invalid padding"); -} - -void -optionToWire(DNSOutput out) { - out.writeU16(family); - out.writeU8(sourceNetmask); - out.writeU8(scopeNetmask); - out.writeByteArray(address.getAddress(), 0, (sourceNetmask + 7) / 8); -} - -String -optionToString() { - StringBuffer sb = new StringBuffer(); - sb.append(address.getHostAddress()); - sb.append("/"); - sb.append(sourceNetmask); - sb.append(", scope netmask "); - sb.append(scopeNetmask); - return sb.toString(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Compression.java b/src/main/java/core/org/xbill/DNS/Compression.java deleted file mode 100644 index e3e81c05..00000000 --- a/src/main/java/core/org/xbill/DNS/Compression.java +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * DNS Name Compression object. - * @see Message - * @see Name - * - * @author Brian Wellington - */ - -public class Compression { - -private static class Entry { - Name name; - int pos; - Entry next; -} - -private static final int TABLE_SIZE = 17; -private static final int MAX_POINTER = 0x3FFF; -private Entry [] table; -private boolean verbose = Options.check("verbosecompression"); - -/** - * Creates a new Compression object. - */ -public -Compression() { - table = new Entry[TABLE_SIZE]; -} - -/** - * Adds a compression entry mapping a name to a position in a message. - * @param pos The position at which the name is added. - * @param name The name being added to the message. - */ -public void -add(int pos, Name name) { - if (pos > MAX_POINTER) - return; - int row = (name.hashCode() & 0x7FFFFFFF) % TABLE_SIZE; - Entry entry = new Entry(); - entry.name = name; - entry.pos = pos; - entry.next = table[row]; - table[row] = entry; - if (verbose) - System.err.println("Adding " + name + " at " + pos); -} - -/** - * Retrieves the position of the given name, if it has been previously - * included in the message. - * @param name The name to find in the compression table. - * @return The position of the name, or -1 if not found. - */ -public int -get(Name name) { - int row = (name.hashCode() & 0x7FFFFFFF) % TABLE_SIZE; - int pos = -1; - for (Entry entry = table[row]; entry != null; entry = entry.next) { - if (entry.name.equals(name)) - pos = entry.pos; - } - if (verbose) - System.err.println("Looking for " + name + ", found " + pos); - return pos; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Credibility.java b/src/main/java/core/org/xbill/DNS/Credibility.java deleted file mode 100644 index fa106868..00000000 --- a/src/main/java/core/org/xbill/DNS/Credibility.java +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Constants relating to the credibility of cached data, which is based on - * the data's source. The constants NORMAL and ANY should be used by most - * callers. - * @see Cache - * @see Section - * - * @author Brian Wellington - */ - -public final class Credibility { - -private -Credibility() {} - -/** A hint or cache file on disk. */ -public static final int HINT = 0; - -/** The additional section of a response. */ -public static final int ADDITIONAL = 1; - -/** The additional section of a response. */ -public static final int GLUE = 2; - -/** The authority section of a nonauthoritative response. */ -public static final int NONAUTH_AUTHORITY = 3; - -/** The answer section of a nonauthoritative response. */ -public static final int NONAUTH_ANSWER = 3; - -/** The authority section of an authoritative response. */ -public static final int AUTH_AUTHORITY = 4; - -/** The answer section of a authoritative response. */ -public static final int AUTH_ANSWER = 4; - -/** A zone. */ -public static final int ZONE = 5; - -/** Credible data. */ -public static final int NORMAL = 3; - -/** Data not required to be credible. */ -public static final int ANY = 1; - -} diff --git a/src/main/java/core/org/xbill/DNS/DClass.java b/src/main/java/core/org/xbill/DNS/DClass.java deleted file mode 100644 index 22180cf4..00000000 --- a/src/main/java/core/org/xbill/DNS/DClass.java +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Constants and functions relating to DNS classes. This is called DClass - * to avoid confusion with Class. - * - * @author Brian Wellington - */ - -public final class DClass { - -/** Internet */ -public static final int IN = 1; - -/** Chaos network (MIT) */ -public static final int CH = 3; - -/** Chaos network (MIT, alternate name) */ -public static final int CHAOS = 3; - -/** Hesiod name server (MIT) */ -public static final int HS = 4; - -/** Hesiod name server (MIT, alternate name) */ -public static final int HESIOD = 4; - -/** Special value used in dynamic update messages */ -public static final int NONE = 254; - -/** Matches any class */ -public static final int ANY = 255; - -private static class DClassMnemonic extends Mnemonic { - public - DClassMnemonic() { - super("DClass", CASE_UPPER); - setPrefix("CLASS"); - } - - public void - check(int val) { - DClass.check(val); - } -} - -private static Mnemonic classes = new DClassMnemonic(); - -static { - classes.add(IN, "IN"); - classes.add(CH, "CH"); - classes.addAlias(CH, "CHAOS"); - classes.add(HS, "HS"); - classes.addAlias(HS, "HESIOD"); - classes.add(NONE, "NONE"); - classes.add(ANY, "ANY"); -} - -private -DClass() {} - -/** - * Checks that a numeric DClass is valid. - * @throws InvalidDClassException The class is out of range. - */ -public static void -check(int i) { - if (i < 0 || i > 0xFFFF) - throw new InvalidDClassException(i); -} - -/** - * Converts a numeric DClass into a String - * @return The canonical string representation of the class - * @throws InvalidDClassException The class is out of range. - */ -public static String -string(int i) { - return classes.getText(i); -} - -/** - * Converts a String representation of a DClass into its numeric value - * @return The class code, or -1 on error. - */ -public static int -value(String s) { - return classes.getValue(s); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/DHCIDRecord.java b/src/main/java/core/org/xbill/DNS/DHCIDRecord.java deleted file mode 100644 index e160a8c9..00000000 --- a/src/main/java/core/org/xbill/DNS/DHCIDRecord.java +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2008 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import org.xbill.DNS.utils.base64; - -/** - * DHCID - Dynamic Host Configuration Protocol (DHCP) ID (RFC 4701) - * - * @author Brian Wellington - */ - -public class DHCIDRecord extends Record { - -private static final long serialVersionUID = -8214820200808997707L; - -private byte [] data; - -DHCIDRecord() {} - -Record -getObject() { - return new DHCIDRecord(); -} - -/** - * Creates an DHCID Record from the given data - * @param data The binary data, which is opaque to DNS. - */ -public -DHCIDRecord(Name name, int dclass, long ttl, byte [] data) { - super(name, Type.DHCID, dclass, ttl); - this.data = data; -} - -void -rrFromWire(DNSInput in) throws IOException { - data = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - data = st.getBase64(); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeByteArray(data); -} - -String -rrToString() { - return base64.toString(data); -} - -/** - * Returns the binary data. - */ -public byte [] -getData() { - return data; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/DLVRecord.java b/src/main/java/core/org/xbill/DNS/DLVRecord.java deleted file mode 100644 index 8acc90f7..00000000 --- a/src/main/java/core/org/xbill/DNS/DLVRecord.java +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) 2002-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import org.xbill.DNS.utils.*; - -/** - * DLV - contains a Delegation Lookaside Validation record, which acts - * as the equivalent of a DS record in a lookaside zone. - * @see DNSSEC - * @see DSRecord - * - * @author David Blacka - * @author Brian Wellington - */ - -public class DLVRecord extends Record { - -public static final int SHA1_DIGEST_ID = DSRecord.Digest.SHA1; -public static final int SHA256_DIGEST_ID = DSRecord.Digest.SHA1; - -private static final long serialVersionUID = 1960742375677534148L; - -private int footprint; -private int alg; -private int digestid; -private byte [] digest; - -DLVRecord() {} - -Record -getObject() { - return new DLVRecord(); -} - -/** - * Creates a DLV Record from the given data - * @param footprint The original KEY record's footprint (keyid). - * @param alg The original key algorithm. - * @param digestid The digest id code. - * @param digest A hash of the original key. - */ -public -DLVRecord(Name name, int dclass, long ttl, int footprint, int alg, - int digestid, byte [] digest) -{ - super(name, Type.DLV, dclass, ttl); - this.footprint = checkU16("footprint", footprint); - this.alg = checkU8("alg", alg); - this.digestid = checkU8("digestid", digestid); - this.digest = digest; -} - -void -rrFromWire(DNSInput in) throws IOException { - footprint = in.readU16(); - alg = in.readU8(); - digestid = in.readU8(); - digest = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - footprint = st.getUInt16(); - alg = st.getUInt8(); - digestid = st.getUInt8(); - digest = st.getHex(); -} - -/** - * Converts rdata to a String - */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(footprint); - sb.append(" "); - sb.append(alg); - sb.append(" "); - sb.append(digestid); - if (digest != null) { - sb.append(" "); - sb.append(base16.toString(digest)); - } - - return sb.toString(); -} - -/** - * Returns the key's algorithm. - */ -public int -getAlgorithm() { - return alg; -} - -/** - * Returns the key's Digest ID. - */ -public int -getDigestID() -{ - return digestid; -} - -/** - * Returns the binary hash of the key. - */ -public byte [] -getDigest() { - return digest; -} - -/** - * Returns the key's footprint. - */ -public int -getFootprint() { - return footprint; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(footprint); - out.writeU8(alg); - out.writeU8(digestid); - if (digest != null) - out.writeByteArray(digest); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/DNAMERecord.java b/src/main/java/core/org/xbill/DNS/DNAMERecord.java deleted file mode 100644 index cbb322f8..00000000 --- a/src/main/java/core/org/xbill/DNS/DNAMERecord.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * DNAME Record - maps a nonterminal alias (subtree) to a different domain - * - * @author Brian Wellington - */ - -public class DNAMERecord extends SingleNameBase { - -private static final long serialVersionUID = 2670767677200844154L; - -DNAMERecord() {} - -Record -getObject() { - return new DNAMERecord(); -} - -/** - * Creates a new DNAMERecord with the given data - * @param alias The name to which the DNAME alias points - */ -public -DNAMERecord(Name name, int dclass, long ttl, Name alias) { - super(name, Type.DNAME, dclass, ttl, alias, "alias"); -} - -/** - * Gets the target of the DNAME Record - */ -public Name -getTarget() { - return getSingleName(); -} - -/** Gets the alias specified by the DNAME Record */ -public Name -getAlias() { - return getSingleName(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/DNSInput.java b/src/main/java/core/org/xbill/DNS/DNSInput.java deleted file mode 100644 index cd66d744..00000000 --- a/src/main/java/core/org/xbill/DNS/DNSInput.java +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.nio.ByteBuffer; - -/** - * An class for parsing DNS messages. - * - * @author Brian Wellington - */ - -public class DNSInput { - -private ByteBuffer byteBuffer; -private int saved_pos; -private int saved_end; - -/** - * Creates a new DNSInput - * @param input The byte array to read from - */ -public -DNSInput(byte [] input) { - byteBuffer = ByteBuffer.wrap(input); - saved_pos = -1; - saved_end = -1; -} - -/** - * Creates a new DNSInput from the given {@link ByteBuffer} - * @param byteBuffer The ByteBuffer - */ -public -DNSInput(ByteBuffer byteBuffer) { - this.byteBuffer = byteBuffer; - saved_pos = -1; - saved_end = -1; -} - -/** - * Returns the current position. - */ -public int -current() { - return byteBuffer.position(); -} - -/** - * Returns the number of bytes that can be read from this stream before - * reaching the end. - */ -public int -remaining() { - return byteBuffer.remaining(); -} - -private void -require(int n) throws WireParseException{ - if (n > remaining()) { - throw new WireParseException("end of input"); - } -} - -/** - * Marks the following bytes in the stream as active. - * @param len The number of bytes in the active region. - * @throws IllegalArgumentException The number of bytes in the active region - * is longer than the remainder of the input. - */ -public void -setActive(int len) { - if (len > byteBuffer.capacity() - byteBuffer.position()) { - throw new IllegalArgumentException("cannot set active " + - "region past end of input"); - } - byteBuffer.limit(byteBuffer.position() + len); -} - -/** - * Clears the active region of the string. Further operations are not - * restricted to part of the input. - */ -public void -clearActive() { - byteBuffer.limit(byteBuffer.capacity()); -} - -/** - * Returns the position of the end of the current active region. - */ -public int -saveActive() { - return byteBuffer.limit(); -} - -/** - * Restores the previously set active region. This differs from setActive() in - * that restoreActive() takes an absolute position, and setActive takes an - * offset from the current location. - * @param pos The end of the active region. - */ -public void -restoreActive(int pos) { - if (pos > byteBuffer.capacity()) { - throw new IllegalArgumentException("cannot set active " + - "region past end of input"); - } - byteBuffer.limit(byteBuffer.position()); -} - -/** - * Resets the current position of the input stream to the specified index, - * and clears the active region. - * @param index The position to continue parsing at. - * @throws IllegalArgumentException The index is not within the input. - */ -public void -jump(int index) { - if (index >= byteBuffer.capacity()) { - throw new IllegalArgumentException("cannot jump past " + - "end of input"); - } - byteBuffer.position(index); - byteBuffer.limit(byteBuffer.capacity()); -} - -/** - * Saves the current state of the input stream. Both the current position and - * the end of the active region are saved. - * @throws IllegalArgumentException The index is not within the input. - */ -public void -save() { - saved_pos = byteBuffer.position(); - saved_end = byteBuffer.limit(); -} - -/** - * Restores the input stream to its state before the call to {@link #save}. - */ -public void -restore() { - if (saved_pos < 0) { - throw new IllegalStateException("no previous state"); - } - byteBuffer.position(saved_pos); - byteBuffer.limit(saved_end); - saved_pos = -1; - saved_end = -1; -} - -/** - * Reads an unsigned 8 bit value from the stream, as an int. - * @return An unsigned 8 bit value. - * @throws WireParseException The end of the stream was reached. - */ -public int -readU8() throws WireParseException { - require(1); - return (byteBuffer.get() & 0xFF); -} - -/** - * Reads an unsigned 16 bit value from the stream, as an int. - * @return An unsigned 16 bit value. - * @throws WireParseException The end of the stream was reached. - */ -public int -readU16() throws WireParseException { - require(2); - return (byteBuffer.getShort() & 0xFFFF); -} - -/** - * Reads an unsigned 32 bit value from the stream, as a long. - * @return An unsigned 32 bit value. - * @throws WireParseException The end of the stream was reached. - */ -public long -readU32() throws WireParseException { - require(4); - return (byteBuffer.getInt() & 0xFFFFFFFFL); -} - -/** - * Reads a byte array of a specified length from the stream into an existing - * array. - * @param b The array to read into. - * @param off The offset of the array to start copying data into. - * @param len The number of bytes to copy. - * @throws WireParseException The end of the stream was reached. - */ -public void -readByteArray(byte [] b, int off, int len) throws WireParseException { - require(len); - byteBuffer.get(b, off, len); -} - -/** - * Reads a byte array of a specified length from the stream. - * @return The byte array. - * @throws WireParseException The end of the stream was reached. - */ -public byte [] -readByteArray(int len) throws WireParseException { - require(len); - byte [] out = new byte[len]; - byteBuffer.get(out, 0, len); - return out; -} - -/** - * Reads a byte array consisting of the remainder of the stream (or the - * active region, if one is set. - * @return The byte array. - */ -public byte [] -readByteArray() { - int len = remaining(); - byte [] out = new byte[len]; - byteBuffer.get(out, 0, len); - return out; -} - -/** - * Reads a counted string from the stream. A counted string is a one byte - * value indicating string length, followed by bytes of data. - * @return A byte array containing the string. - * @throws WireParseException The end of the stream was reached. - */ -public byte [] -readCountedString() throws WireParseException { - int len = readU8(); - return readByteArray(len); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/DNSKEYRecord.java b/src/main/java/core/org/xbill/DNS/DNSKEYRecord.java deleted file mode 100644 index 6e9bafdf..00000000 --- a/src/main/java/core/org/xbill/DNS/DNSKEYRecord.java +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.security.PublicKey; - -/** - * Key - contains a cryptographic public key for use by DNS. - * The data can be converted to objects implementing - * java.security.interfaces.PublicKey - * @see DNSSEC - * - * @author Brian Wellington - */ - -public class DNSKEYRecord extends KEYBase { - -public static class Protocol { - private Protocol() {} - - /** Key will be used for DNSSEC */ - public static final int DNSSEC = 3; -} - -public static class Flags { - private Flags() {} - - /** Key is a zone key */ - public static final int ZONE_KEY = 0x100; - - /** Key is a secure entry point key */ - public static final int SEP_KEY = 0x1; - - /** Key has been revoked */ - public static final int REVOKE = 0x80; -} - -private static final long serialVersionUID = -8679800040426675002L; - -DNSKEYRecord() {} - -Record -getObject() { - return new DNSKEYRecord(); -} - -/** - * Creates a DNSKEY Record from the given data - * @param flags Flags describing the key's properties - * @param proto The protocol that the key was created for - * @param alg The key's algorithm - * @param key Binary representation of the key - */ -public -DNSKEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg, - byte [] key) -{ - super(name, Type.DNSKEY, dclass, ttl, flags, proto, alg, key); -} - -/** - * Creates a DNSKEY Record from the given data - * @param flags Flags describing the key's properties - * @param proto The protocol that the key was created for - * @param alg The key's algorithm - * @param key The key as a PublicKey - * @throws DNSSEC.DNSSECException The PublicKey could not be converted into DNS - * format. - */ -public -DNSKEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg, - PublicKey key) throws DNSSEC.DNSSECException -{ - super(name, Type.DNSKEY, dclass, ttl, flags, proto, alg, - DNSSEC.fromPublicKey(key, alg)); - publicKey = key; -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - flags = st.getUInt16(); - proto = st.getUInt8(); - String algString = st.getString(); - alg = DNSSEC.Algorithm.value(algString); - if (alg < 0) - throw st.exception("Invalid algorithm: " + algString); - key = st.getBase64(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/DNSOutput.java b/src/main/java/core/org/xbill/DNS/DNSOutput.java deleted file mode 100644 index 29a8f68d..00000000 --- a/src/main/java/core/org/xbill/DNS/DNSOutput.java +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * A class for rendering DNS messages. - * - * @author Brian Wellington - */ - - -public class DNSOutput { - -private byte [] array; -private int pos; -private int saved_pos; - -/** - * Create a new DNSOutput with a specified size. - * @param size The initial size - */ -public -DNSOutput(int size) { - array = new byte[size]; - pos = 0; - saved_pos = -1; -} - -/** - * Create a new DNSOutput - */ -public -DNSOutput() { - this(32); -} - -/** - * Returns the current position. - */ -public int -current() { - return pos; -} - -private void -check(long val, int bits) { - long max = 1; - max <<= bits; - if (val < 0 || val > max) { - throw new IllegalArgumentException(val + " out of range for " + - bits + " bit value"); - } -} - -private void -need(int n) { - if (array.length - pos >= n) { - return; - } - int newsize = array.length * 2; - if (newsize < pos + n) { - newsize = pos + n; - } - byte [] newarray = new byte[newsize]; - System.arraycopy(array, 0, newarray, 0, pos); - array = newarray; -} - -/** - * Resets the current position of the output stream to the specified index. - * @param index The new current position. - * @throws IllegalArgumentException The index is not within the output. - */ -public void -jump(int index) { - if (index > pos) { - throw new IllegalArgumentException("cannot jump past " + - "end of data"); - } - pos = index; -} - -/** - * Saves the current state of the output stream. - * @throws IllegalArgumentException The index is not within the output. - */ -public void -save() { - saved_pos = pos; -} - -/** - * Restores the input stream to its state before the call to {@link #save}. - */ -public void -restore() { - if (saved_pos < 0) { - throw new IllegalStateException("no previous state"); - } - pos = saved_pos; - saved_pos = -1; -} - -/** - * Writes an unsigned 8 bit value to the stream. - * @param val The value to be written - */ -public void -writeU8(int val) { - check(val, 8); - need(1); - array[pos++] = (byte)(val & 0xFF); -} - -/** - * Writes an unsigned 16 bit value to the stream. - * @param val The value to be written - */ -public void -writeU16(int val) { - check(val, 16); - need(2); - array[pos++] = (byte)((val >>> 8) & 0xFF); - array[pos++] = (byte)(val & 0xFF); -} - -/** - * Writes an unsigned 16 bit value to the specified position in the stream. - * @param val The value to be written - * @param where The position to write the value. - */ -public void -writeU16At(int val, int where) { - check(val, 16); - if (where > pos - 2) - throw new IllegalArgumentException("cannot write past " + - "end of data"); - array[where++] = (byte)((val >>> 8) & 0xFF); - array[where++] = (byte)(val & 0xFF); -} - -/** - * Writes an unsigned 32 bit value to the stream. - * @param val The value to be written - */ -public void -writeU32(long val) { - check(val, 32); - need(4); - array[pos++] = (byte)((val >>> 24) & 0xFF); - array[pos++] = (byte)((val >>> 16) & 0xFF); - array[pos++] = (byte)((val >>> 8) & 0xFF); - array[pos++] = (byte)(val & 0xFF); -} - -/** - * Writes a byte array to the stream. - * @param b The array to write. - * @param off The offset of the array to start copying data from. - * @param len The number of bytes to write. - */ -public void -writeByteArray(byte [] b, int off, int len) { - need(len); - System.arraycopy(b, off, array, pos, len); - pos += len; -} - -/** - * Writes a byte array to the stream. - * @param b The array to write. - */ -public void -writeByteArray(byte [] b) { - writeByteArray(b, 0, b.length); -} - -/** - * Writes a counted string from the stream. A counted string is a one byte - * value indicating string length, followed by bytes of data. - * @param s The string to write. - */ -public void -writeCountedString(byte [] s) { - if (s.length > 0xFF) { - throw new IllegalArgumentException("Invalid counted string"); - } - need(1 + s.length); - array[pos++] = (byte)(s.length & 0xFF); - writeByteArray(s, 0, s.length); -} - -/** - * Returns a byte array containing the current contents of the stream. - */ -public byte [] -toByteArray() { - byte [] out = new byte[pos]; - System.arraycopy(array, 0, out, 0, pos); - return out; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/DNSSEC.java b/src/main/java/core/org/xbill/DNS/DNSSEC.java deleted file mode 100644 index 23b764f2..00000000 --- a/src/main/java/core/org/xbill/DNS/DNSSEC.java +++ /dev/null @@ -1,1168 +0,0 @@ -// Copyright (c) 1999-2010 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.math.*; -import java.security.*; -import java.security.interfaces.*; -import java.security.spec.*; -import java.util.*; - -/** - * Constants and methods relating to DNSSEC. - * - * DNSSEC provides authentication for DNS information. - * @see RRSIGRecord - * @see DNSKEYRecord - * @see RRset - * - * @author Brian Wellington - */ - -public class DNSSEC { - -public static class Algorithm { - private Algorithm() {} - - /** RSA/MD5 public key (deprecated) */ - public static final int RSAMD5 = 1; - - /** Diffie Hellman key */ - public static final int DH = 2; - - /** DSA public key */ - public static final int DSA = 3; - - /** RSA/SHA1 public key */ - public static final int RSASHA1 = 5; - - /** DSA/SHA1, NSEC3-aware public key */ - public static final int DSA_NSEC3_SHA1 = 6; - - /** RSA/SHA1, NSEC3-aware public key */ - public static final int RSA_NSEC3_SHA1 = 7; - - /** RSA/SHA256 public key */ - public static final int RSASHA256 = 8; - - /** RSA/SHA512 public key */ - public static final int RSASHA512 = 10; - - /** GOST R 34.10-2001. - * This requires an external cryptography provider, - * such as BouncyCastle. - */ - public static final int ECC_GOST = 12; - - /** ECDSA Curve P-256 with SHA-256 public key **/ - public static final int ECDSAP256SHA256 = 13; - - /** ECDSA Curve P-384 with SHA-384 public key **/ - public static final int ECDSAP384SHA384 = 14; - - /** Indirect keys; the actual key is elsewhere. */ - public static final int INDIRECT = 252; - - /** Private algorithm, specified by domain name */ - public static final int PRIVATEDNS = 253; - - /** Private algorithm, specified by OID */ - public static final int PRIVATEOID = 254; - - private static Mnemonic algs = new Mnemonic("DNSSEC algorithm", - Mnemonic.CASE_UPPER); - - static { - algs.setMaximum(0xFF); - algs.setNumericAllowed(true); - - algs.add(RSAMD5, "RSAMD5"); - algs.add(DH, "DH"); - algs.add(DSA, "DSA"); - algs.add(RSASHA1, "RSASHA1"); - algs.add(DSA_NSEC3_SHA1, "DSA-NSEC3-SHA1"); - algs.add(RSA_NSEC3_SHA1, "RSA-NSEC3-SHA1"); - algs.add(RSASHA256, "RSASHA256"); - algs.add(RSASHA512, "RSASHA512"); - algs.add(ECC_GOST, "ECC-GOST"); - algs.add(ECDSAP256SHA256, "ECDSAP256SHA256"); - algs.add(ECDSAP384SHA384, "ECDSAP384SHA384"); - algs.add(INDIRECT, "INDIRECT"); - algs.add(PRIVATEDNS, "PRIVATEDNS"); - algs.add(PRIVATEOID, "PRIVATEOID"); - } - - /** - * Converts an algorithm into its textual representation - */ - public static String - string(int alg) { - return algs.getText(alg); - } - - /** - * Converts a textual representation of an algorithm into its numeric - * code. Integers in the range 0..255 are also accepted. - * @param s The textual representation of the algorithm - * @return The algorithm code, or -1 on error. - */ - public static int - value(String s) { - return algs.getValue(s); - } -} - -private -DNSSEC() { } - -private static void -digestSIG(DNSOutput out, SIGBase sig) { - out.writeU16(sig.getTypeCovered()); - out.writeU8(sig.getAlgorithm()); - out.writeU8(sig.getLabels()); - out.writeU32(sig.getOrigTTL()); - out.writeU32(sig.getExpire().getTime() / 1000); - out.writeU32(sig.getTimeSigned().getTime() / 1000); - out.writeU16(sig.getFootprint()); - sig.getSigner().toWireCanonical(out); -} - -/** - * Creates a byte array containing the concatenation of the fields of the - * SIG record and the RRsets to be signed/verified. This does not perform - * a cryptographic digest. - * @param rrsig The RRSIG record used to sign/verify the rrset. - * @param rrset The data to be signed/verified. - * @return The data to be cryptographically signed or verified. - */ -public static byte [] -digestRRset(RRSIGRecord rrsig, RRset rrset) { - DNSOutput out = new DNSOutput(); - digestSIG(out, rrsig); - - int size = rrset.size(); - Record [] records = new Record[size]; - - Iterator it = rrset.rrs(); - Name name = rrset.getName(); - Name wild = null; - int sigLabels = rrsig.getLabels() + 1; // Add the root label back. - if (name.labels() > sigLabels) - wild = name.wild(name.labels() - sigLabels); - while (it.hasNext()) - records[--size] = (Record) it.next(); - Arrays.sort(records); - - DNSOutput header = new DNSOutput(); - if (wild != null) - wild.toWireCanonical(header); - else - name.toWireCanonical(header); - header.writeU16(rrset.getType()); - header.writeU16(rrset.getDClass()); - header.writeU32(rrsig.getOrigTTL()); - for (int i = 0; i < records.length; i++) { - out.writeByteArray(header.toByteArray()); - int lengthPosition = out.current(); - out.writeU16(0); - out.writeByteArray(records[i].rdataToWireCanonical()); - int rrlength = out.current() - lengthPosition - 2; - out.save(); - out.jump(lengthPosition); - out.writeU16(rrlength); - out.restore(); - } - return out.toByteArray(); -} - -/** - * Creates a byte array containing the concatenation of the fields of the - * SIG(0) record and the message to be signed. This does not perform - * a cryptographic digest. - * @param sig The SIG record used to sign the rrset. - * @param msg The message to be signed. - * @param previous If this is a response, the signature from the query. - * @return The data to be cryptographically signed. - */ -public static byte [] -digestMessage(SIGRecord sig, Message msg, byte [] previous) { - DNSOutput out = new DNSOutput(); - digestSIG(out, sig); - - if (previous != null) - out.writeByteArray(previous); - - msg.toWire(out); - return out.toByteArray(); -} - -/** - * A DNSSEC exception. - */ -public static class DNSSECException extends Exception { - DNSSECException(String s) { - super(s); - } -} - -/** - * An algorithm is unsupported by this DNSSEC implementation. - */ -public static class UnsupportedAlgorithmException extends DNSSECException { - UnsupportedAlgorithmException(int alg) { - super("Unsupported algorithm: " + alg); - } -} - -/** - * The cryptographic data in a DNSSEC key is malformed. - */ -public static class MalformedKeyException extends DNSSECException { - MalformedKeyException(KEYBase rec) { - super("Invalid key data: " + rec.rdataToString()); - } -} - -/** - * A DNSSEC verification failed because fields in the DNSKEY and RRSIG records - * do not match. - */ -public static class KeyMismatchException extends DNSSECException { - private KEYBase key; - private SIGBase sig; - - KeyMismatchException(KEYBase key, SIGBase sig) { - super("key " + - key.getName() + "/" + - DNSSEC.Algorithm.string(key.getAlgorithm()) + "/" + - key.getFootprint() + " " + - "does not match signature " + - sig.getSigner() + "/" + - DNSSEC.Algorithm.string(sig.getAlgorithm()) + "/" + - sig.getFootprint()); - } -} - -/** - * A DNSSEC verification failed because the signature has expired. - */ -public static class SignatureExpiredException extends DNSSECException { - private Date when, now; - - SignatureExpiredException(Date when, Date now) { - super("signature expired"); - this.when = when; - this.now = now; - } - - /** - * @return When the signature expired - */ - public Date - getExpiration() { - return when; - } - - /** - * @return When the verification was attempted - */ - public Date - getVerifyTime() { - return now; - } -} - -/** - * A DNSSEC verification failed because the signature has not yet become valid. - */ -public static class SignatureNotYetValidException extends DNSSECException { - private Date when, now; - - SignatureNotYetValidException(Date when, Date now) { - super("signature is not yet valid"); - this.when = when; - this.now = now; - } - - /** - * @return When the signature will become valid - */ - public Date - getExpiration() { - return when; - } - - /** - * @return When the verification was attempted - */ - public Date - getVerifyTime() { - return now; - } -} - -/** - * A DNSSEC verification failed because the cryptographic signature - * verification failed. - */ -public static class SignatureVerificationException extends DNSSECException { - SignatureVerificationException() { - super("signature verification failed"); - } -} - -/** - * The key data provided is inconsistent. - */ -public static class IncompatibleKeyException extends IllegalArgumentException { - IncompatibleKeyException() { - super("incompatible keys"); - } -} - -/** - * No signature was found. - */ -public static class NoSignatureException extends DNSSECException { - NoSignatureException() { - super("no signature found"); - } -} - -private static int -BigIntegerLength(BigInteger i) { - return (i.bitLength() + 7) / 8; -} - -private static BigInteger -readBigInteger(DNSInput in, int len) throws IOException { - byte [] b = in.readByteArray(len); - return new BigInteger(1, b); -} - -private static BigInteger -readBigInteger(DNSInput in) { - byte [] b = in.readByteArray(); - return new BigInteger(1, b); -} - -private static byte [] -trimByteArray(byte [] array) { - if (array[0] == 0) { - byte trimmedArray[] = new byte[array.length - 1]; - System.arraycopy(array, 1, trimmedArray, 0, array.length - 1); - return trimmedArray; - } else { - return array; - } -} - -private static void -reverseByteArray(byte [] array) { - for (int i = 0; i < array.length / 2; i++) { - int j = array.length - i - 1; - byte tmp = array[i]; - array[i] = array[j]; - array[j] = tmp; - } -} - -private static BigInteger -readBigIntegerLittleEndian(DNSInput in, int len) throws IOException { - byte [] b = in.readByteArray(len); - reverseByteArray(b); - return new BigInteger(1, b); -} - -private static void -writeBigInteger(DNSOutput out, BigInteger val) { - byte [] b = trimByteArray(val.toByteArray()); - out.writeByteArray(b); -} - -private static void -writePaddedBigInteger(DNSOutput out, BigInteger val, int len) { - byte [] b = trimByteArray(val.toByteArray()); - - if (b.length > len) - throw new IllegalArgumentException(); - - if (b.length < len) { - byte [] pad = new byte[len - b.length]; - out.writeByteArray(pad); - } - - out.writeByteArray(b); -} - -private static void -writePaddedBigIntegerLittleEndian(DNSOutput out, BigInteger val, int len) { - byte [] b = trimByteArray(val.toByteArray()); - - if (b.length > len) - throw new IllegalArgumentException(); - - reverseByteArray(b); - out.writeByteArray(b); - - if (b.length < len) { - byte [] pad = new byte[len - b.length]; - out.writeByteArray(pad); - } -} - -private static PublicKey -toRSAPublicKey(KEYBase r) throws IOException, GeneralSecurityException { - DNSInput in = new DNSInput(r.getKey()); - int exponentLength = in.readU8(); - if (exponentLength == 0) - exponentLength = in.readU16(); - BigInteger exponent = readBigInteger(in, exponentLength); - BigInteger modulus = readBigInteger(in); - - KeyFactory factory = KeyFactory.getInstance("RSA"); - return factory.generatePublic(new RSAPublicKeySpec(modulus, exponent)); -} - -private static PublicKey -toDSAPublicKey(KEYBase r) throws IOException, GeneralSecurityException, - MalformedKeyException -{ - DNSInput in = new DNSInput(r.getKey()); - - int t = in.readU8(); - if (t > 8) - throw new MalformedKeyException(r); - - BigInteger q = readBigInteger(in, 20); - BigInteger p = readBigInteger(in, 64 + t*8); - BigInteger g = readBigInteger(in, 64 + t*8); - BigInteger y = readBigInteger(in, 64 + t*8); - - KeyFactory factory = KeyFactory.getInstance("DSA"); - return factory.generatePublic(new DSAPublicKeySpec(y, p, q, g)); -} - -private static class ECKeyInfo { - int length; - public BigInteger p, a, b, gx, gy, n; - EllipticCurve curve; - ECParameterSpec spec; - - ECKeyInfo(int length, String p_str, String a_str, String b_str, - String gx_str, String gy_str, String n_str) - { - this.length = length; - p = new BigInteger(p_str, 16); - a = new BigInteger(a_str, 16); - b = new BigInteger(b_str, 16); - gx = new BigInteger(gx_str, 16); - gy = new BigInteger(gy_str, 16); - n = new BigInteger(n_str, 16); - curve = new EllipticCurve(new ECFieldFp(p), a, b); - spec = new ECParameterSpec(curve, new ECPoint(gx, gy), n, 1); - } -} - -// RFC 4357 Section 11.4 -private static final ECKeyInfo GOST = new ECKeyInfo(32, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", - "A6", - "1", - "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893"); - -// RFC 5114 Section 2.6 -private static final ECKeyInfo ECDSA_P256 = new ECKeyInfo(32, - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", - "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", - "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); - -// RFC 5114 Section 2.7 -private static final ECKeyInfo ECDSA_P384 = new ECKeyInfo(48, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", - "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", - "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", - "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"); - -private static PublicKey -toECGOSTPublicKey(KEYBase r, ECKeyInfo keyinfo) throws IOException, - GeneralSecurityException, MalformedKeyException -{ - DNSInput in = new DNSInput(r.getKey()); - - BigInteger x = readBigIntegerLittleEndian(in, keyinfo.length); - BigInteger y = readBigIntegerLittleEndian(in, keyinfo.length); - ECPoint q = new ECPoint(x, y); - - KeyFactory factory = KeyFactory.getInstance("ECGOST3410"); - return factory.generatePublic(new ECPublicKeySpec(q, keyinfo.spec)); -} - -private static PublicKey -toECDSAPublicKey(KEYBase r, ECKeyInfo keyinfo) throws IOException, - GeneralSecurityException, MalformedKeyException -{ - DNSInput in = new DNSInput(r.getKey()); - - // RFC 6605 Section 4 - BigInteger x = readBigInteger(in, keyinfo.length); - BigInteger y = readBigInteger(in, keyinfo.length); - ECPoint q = new ECPoint(x, y); - - KeyFactory factory = KeyFactory.getInstance("EC"); - return factory.generatePublic(new ECPublicKeySpec(q, keyinfo.spec)); -} - -/** Converts a KEY/DNSKEY record into a PublicKey */ -static PublicKey -toPublicKey(KEYBase r) throws DNSSECException { - int alg = r.getAlgorithm(); - try { - switch (alg) { - case Algorithm.RSAMD5: - case Algorithm.RSASHA1: - case Algorithm.RSA_NSEC3_SHA1: - case Algorithm.RSASHA256: - case Algorithm.RSASHA512: - return toRSAPublicKey(r); - case Algorithm.DSA: - case Algorithm.DSA_NSEC3_SHA1: - return toDSAPublicKey(r); - case Algorithm.ECC_GOST: - return toECGOSTPublicKey(r, GOST); - case Algorithm.ECDSAP256SHA256: - return toECDSAPublicKey(r, ECDSA_P256); - case Algorithm.ECDSAP384SHA384: - return toECDSAPublicKey(r, ECDSA_P384); - default: - throw new UnsupportedAlgorithmException(alg); - } - } - catch (IOException e) { - throw new MalformedKeyException(r); - } - catch (GeneralSecurityException e) { - throw new DNSSECException(e.toString()); - } -} - -private static byte [] -fromRSAPublicKey(RSAPublicKey key) { - DNSOutput out = new DNSOutput(); - BigInteger exponent = key.getPublicExponent(); - BigInteger modulus = key.getModulus(); - int exponentLength = BigIntegerLength(exponent); - - if (exponentLength < 256) - out.writeU8(exponentLength); - else { - out.writeU8(0); - out.writeU16(exponentLength); - } - writeBigInteger(out, exponent); - writeBigInteger(out, modulus); - - return out.toByteArray(); -} - -private static byte [] -fromDSAPublicKey(DSAPublicKey key) { - DNSOutput out = new DNSOutput(); - BigInteger q = key.getParams().getQ(); - BigInteger p = key.getParams().getP(); - BigInteger g = key.getParams().getG(); - BigInteger y = key.getY(); - int t = (p.toByteArray().length - 64) / 8; - - out.writeU8(t); - writeBigInteger(out, q); - writeBigInteger(out, p); - writePaddedBigInteger(out, g, 8 * t + 64); - writePaddedBigInteger(out, y, 8 * t + 64); - - return out.toByteArray(); -} - -private static byte [] -fromECGOSTPublicKey(ECPublicKey key, ECKeyInfo keyinfo) { - DNSOutput out = new DNSOutput(); - - BigInteger x = key.getW().getAffineX(); - BigInteger y = key.getW().getAffineY(); - - writePaddedBigIntegerLittleEndian(out, x, keyinfo.length); - writePaddedBigIntegerLittleEndian(out, y, keyinfo.length); - - return out.toByteArray(); -} - -private static byte [] -fromECDSAPublicKey(ECPublicKey key, ECKeyInfo keyinfo) { - DNSOutput out = new DNSOutput(); - - BigInteger x = key.getW().getAffineX(); - BigInteger y = key.getW().getAffineY(); - - writePaddedBigInteger(out, x, keyinfo.length); - writePaddedBigInteger(out, y, keyinfo.length); - - return out.toByteArray(); -} - -/** Builds a DNSKEY record from a PublicKey */ -static byte [] -fromPublicKey(PublicKey key, int alg) throws DNSSECException -{ - switch (alg) { - case Algorithm.RSAMD5: - case Algorithm.RSASHA1: - case Algorithm.RSA_NSEC3_SHA1: - case Algorithm.RSASHA256: - case Algorithm.RSASHA512: - if (! (key instanceof RSAPublicKey)) - throw new IncompatibleKeyException(); - return fromRSAPublicKey((RSAPublicKey) key); - case Algorithm.DSA: - case Algorithm.DSA_NSEC3_SHA1: - if (! (key instanceof DSAPublicKey)) - throw new IncompatibleKeyException(); - return fromDSAPublicKey((DSAPublicKey) key); - case Algorithm.ECC_GOST: - if (! (key instanceof ECPublicKey)) - throw new IncompatibleKeyException(); - return fromECGOSTPublicKey((ECPublicKey) key, GOST); - case Algorithm.ECDSAP256SHA256: - if (! (key instanceof ECPublicKey)) - throw new IncompatibleKeyException(); - return fromECDSAPublicKey((ECPublicKey) key, ECDSA_P256); - case Algorithm.ECDSAP384SHA384: - if (! (key instanceof ECPublicKey)) - throw new IncompatibleKeyException(); - return fromECDSAPublicKey((ECPublicKey) key, ECDSA_P384); - default: - throw new UnsupportedAlgorithmException(alg); - } -} - -/** - * Convert an algorithm number to the corresponding JCA string. - * @param alg The algorithm number. - * @throws UnsupportedAlgorithmException The algorithm is unknown. - */ -public static String -algString(int alg) throws UnsupportedAlgorithmException { - switch (alg) { - case Algorithm.RSAMD5: - return "MD5withRSA"; - case Algorithm.DSA: - case Algorithm.DSA_NSEC3_SHA1: - return "SHA1withDSA"; - case Algorithm.RSASHA1: - case Algorithm.RSA_NSEC3_SHA1: - return "SHA1withRSA"; - case Algorithm.RSASHA256: - return "SHA256withRSA"; - case Algorithm.RSASHA512: - return "SHA512withRSA"; - case Algorithm.ECC_GOST: - return "GOST3411withECGOST3410"; - case Algorithm.ECDSAP256SHA256: - return "SHA256withECDSA"; - case Algorithm.ECDSAP384SHA384: - return "SHA384withECDSA"; - default: - throw new UnsupportedAlgorithmException(alg); - } -} - -private static final int ASN1_SEQ = 0x30; -private static final int ASN1_INT = 0x2; - -private static final int DSA_LEN = 20; - -private static byte [] -DSASignaturefromDNS(byte [] dns) throws DNSSECException, IOException { - if (dns.length != 1 + DSA_LEN * 2) - throw new SignatureVerificationException(); - - DNSInput in = new DNSInput(dns); - DNSOutput out = new DNSOutput(); - - int t = in.readU8(); - - byte [] r = in.readByteArray(DSA_LEN); - int rlen = DSA_LEN; - if (r[0] < 0) - rlen++; - - byte [] s = in.readByteArray(DSA_LEN); - int slen = DSA_LEN; - if (s[0] < 0) - slen++; - - out.writeU8(ASN1_SEQ); - out.writeU8(rlen + slen + 4); - - out.writeU8(ASN1_INT); - out.writeU8(rlen); - if (rlen > DSA_LEN) - out.writeU8(0); - out.writeByteArray(r); - - out.writeU8(ASN1_INT); - out.writeU8(slen); - if (slen > DSA_LEN) - out.writeU8(0); - out.writeByteArray(s); - - return out.toByteArray(); -} - -private static byte [] -DSASignaturetoDNS(byte [] signature, int t) throws IOException { - DNSInput in = new DNSInput(signature); - DNSOutput out = new DNSOutput(); - - out.writeU8(t); - - int tmp = in.readU8(); - if (tmp != ASN1_SEQ) - throw new IOException(); - int seqlen = in.readU8(); - - tmp = in.readU8(); - if (tmp != ASN1_INT) - throw new IOException(); - int rlen = in.readU8(); - if (rlen == DSA_LEN + 1) { - if (in.readU8() != 0) - throw new IOException(); - } else if (rlen != DSA_LEN) - throw new IOException(); - byte [] bytes = in.readByteArray(DSA_LEN); - out.writeByteArray(bytes); - - tmp = in.readU8(); - if (tmp != ASN1_INT) - throw new IOException(); - int slen = in.readU8(); - if (slen == DSA_LEN + 1) { - if (in.readU8() != 0) - throw new IOException(); - } else if (slen != DSA_LEN) - throw new IOException(); - bytes = in.readByteArray(DSA_LEN); - out.writeByteArray(bytes); - - return out.toByteArray(); -} - -private static byte [] -ECGOSTSignaturefromDNS(byte [] signature, ECKeyInfo keyinfo) - throws DNSSECException, IOException -{ - if (signature.length != keyinfo.length * 2) - throw new SignatureVerificationException(); - // Wire format is equal to the engine input - return signature; -} - -private static byte [] -ECDSASignaturefromDNS(byte [] signature, ECKeyInfo keyinfo) - throws DNSSECException, IOException -{ - if (signature.length != keyinfo.length * 2) - throw new SignatureVerificationException(); - - DNSInput in = new DNSInput(signature); - DNSOutput out = new DNSOutput(); - - byte [] r = in.readByteArray(keyinfo.length); - int rlen = keyinfo.length; - if (r[0] < 0) - rlen++; - - byte [] s = in.readByteArray(keyinfo.length); - int slen = keyinfo.length; - if (s[0] < 0) - slen++; - - out.writeU8(ASN1_SEQ); - out.writeU8(rlen + slen + 4); - - out.writeU8(ASN1_INT); - out.writeU8(rlen); - if (rlen > keyinfo.length) - out.writeU8(0); - out.writeByteArray(r); - - out.writeU8(ASN1_INT); - out.writeU8(slen); - if (slen > keyinfo.length) - out.writeU8(0); - out.writeByteArray(s); - - return out.toByteArray(); -} - -private static byte [] -ECDSASignaturetoDNS(byte [] signature, ECKeyInfo keyinfo) throws IOException { - DNSInput in = new DNSInput(signature); - DNSOutput out = new DNSOutput(); - - int tmp = in.readU8(); - if (tmp != ASN1_SEQ) - throw new IOException(); - int seqlen = in.readU8(); - - tmp = in.readU8(); - if (tmp != ASN1_INT) - throw new IOException(); - int rlen = in.readU8(); - if (rlen == keyinfo.length + 1) { - if (in.readU8() != 0) - throw new IOException(); - } else if (rlen != keyinfo.length) - throw new IOException(); - byte[] bytes = in.readByteArray(keyinfo.length); - out.writeByteArray(bytes); - - tmp = in.readU8(); - if (tmp != ASN1_INT) - throw new IOException(); - int slen = in.readU8(); - if (slen == keyinfo.length + 1) { - if (in.readU8() != 0) - throw new IOException(); - } else if (slen != keyinfo.length) - throw new IOException(); - bytes = in.readByteArray(keyinfo.length); - out.writeByteArray(bytes); - - return out.toByteArray(); -} - -private static void -verify(PublicKey key, int alg, byte [] data, byte [] signature) -throws DNSSECException -{ - if (key instanceof DSAPublicKey) { - try { - signature = DSASignaturefromDNS(signature); - } - catch (IOException e) { - throw new IllegalStateException(); - } - } else if (key instanceof ECPublicKey) { - try { - switch (alg) { - case Algorithm.ECC_GOST: - signature = ECGOSTSignaturefromDNS(signature, - GOST); - break; - case Algorithm.ECDSAP256SHA256: - signature = ECDSASignaturefromDNS(signature, - ECDSA_P256); - break; - case Algorithm.ECDSAP384SHA384: - signature = ECDSASignaturefromDNS(signature, - ECDSA_P384); - break; - default: - throw new UnsupportedAlgorithmException(alg); - } - } - catch (IOException e) { - throw new IllegalStateException(); - } - } - - try { - Signature s = Signature.getInstance(algString(alg)); - s.initVerify(key); - s.update(data); - if (!s.verify(signature)) - throw new SignatureVerificationException(); - } - catch (GeneralSecurityException e) { - throw new DNSSECException(e.toString()); - } -} - -private static boolean -matches(SIGBase sig, KEYBase key) -{ - return (key.getAlgorithm() == sig.getAlgorithm() && - key.getFootprint() == sig.getFootprint() && - key.getName().equals(sig.getSigner())); -} - -/** - * Verify a DNSSEC signature. - * @param rrset The data to be verified. - * @param rrsig The RRSIG record containing the signature. - * @param key The DNSKEY record to verify the signature with. - * @throws UnsupportedAlgorithmException The algorithm is unknown - * @throws MalformedKeyException The key is malformed - * @throws KeyMismatchException The key and signature do not match - * @throws SignatureExpiredException The signature has expired - * @throws SignatureNotYetValidException The signature is not yet valid - * @throws SignatureVerificationException The signature does not verify. - * @throws DNSSECException Some other error occurred. - */ -public static void -verify(RRset rrset, RRSIGRecord rrsig, DNSKEYRecord key) throws DNSSECException -{ - if (!matches(rrsig, key)) - throw new KeyMismatchException(key, rrsig); - - Date now = new Date(); - if (now.compareTo(rrsig.getExpire()) > 0) - throw new SignatureExpiredException(rrsig.getExpire(), now); - if (now.compareTo(rrsig.getTimeSigned()) < 0) - throw new SignatureNotYetValidException(rrsig.getTimeSigned(), - now); - - verify(key.getPublicKey(), rrsig.getAlgorithm(), - digestRRset(rrsig, rrset), rrsig.getSignature()); -} - -private static byte [] -sign(PrivateKey privkey, PublicKey pubkey, int alg, byte [] data, - String provider) throws DNSSECException -{ - byte [] signature; - try { - Signature s; - if (provider != null) - s = Signature.getInstance(algString(alg), provider); - else - s = Signature.getInstance(algString(alg)); - s.initSign(privkey); - s.update(data); - signature = s.sign(); - } - catch (GeneralSecurityException e) { - throw new DNSSECException(e.toString()); - } - - if (pubkey instanceof DSAPublicKey) { - try { - DSAPublicKey dsa = (DSAPublicKey) pubkey; - BigInteger P = dsa.getParams().getP(); - int t = (BigIntegerLength(P) - 64) / 8; - signature = DSASignaturetoDNS(signature, t); - } - catch (IOException e) { - throw new IllegalStateException(); - } - } else if (pubkey instanceof ECPublicKey) { - try { - switch (alg) { - case Algorithm.ECC_GOST: - // Wire format is equal to the engine output - break; - case Algorithm.ECDSAP256SHA256: - signature = ECDSASignaturetoDNS(signature, - ECDSA_P256); - break; - case Algorithm.ECDSAP384SHA384: - signature = ECDSASignaturetoDNS(signature, - ECDSA_P384); - break; - default: - throw new UnsupportedAlgorithmException(alg); - } - } - catch (IOException e) { - throw new IllegalStateException(); - } - } - - return signature; -} -static void -checkAlgorithm(PrivateKey key, int alg) throws UnsupportedAlgorithmException -{ - switch (alg) { - case Algorithm.RSAMD5: - case Algorithm.RSASHA1: - case Algorithm.RSA_NSEC3_SHA1: - case Algorithm.RSASHA256: - case Algorithm.RSASHA512: - if (! (key instanceof RSAPrivateKey)) - throw new IncompatibleKeyException(); - break; - case Algorithm.DSA: - case Algorithm.DSA_NSEC3_SHA1: - if (! (key instanceof DSAPrivateKey)) - throw new IncompatibleKeyException(); - break; - case Algorithm.ECC_GOST: - case Algorithm.ECDSAP256SHA256: - case Algorithm.ECDSAP384SHA384: - if (! (key instanceof ECPrivateKey)) - throw new IncompatibleKeyException(); - break; - default: - throw new UnsupportedAlgorithmException(alg); - } -} - -/** - * Generate a DNSSEC signature. key and privateKey must refer to the - * same underlying cryptographic key. - * @param rrset The data to be signed - * @param key The DNSKEY record to use as part of signing - * @param privkey The PrivateKey to use when signing - * @param inception The time at which the signatures should become valid - * @param expiration The time at which the signatures should expire - * @throws UnsupportedAlgorithmException The algorithm is unknown - * @throws MalformedKeyException The key is malformed - * @throws DNSSECException Some other error occurred. - * @return The generated signature - */ -public static RRSIGRecord -sign(RRset rrset, DNSKEYRecord key, PrivateKey privkey, - Date inception, Date expiration) throws DNSSECException -{ - return sign(rrset, key, privkey, inception, expiration, null); -} - -/** - * Generate a DNSSEC signature. key and privateKey must refer to the - * same underlying cryptographic key. - * @param rrset The data to be signed - * @param key The DNSKEY record to use as part of signing - * @param privkey The PrivateKey to use when signing - * @param inception The time at which the signatures should become valid - * @param expiration The time at which the signatures should expire - * @param provider The name of the JCA provider. If non-null, it will be - * passed to JCA getInstance() methods. - * @throws UnsupportedAlgorithmException The algorithm is unknown - * @throws MalformedKeyException The key is malformed - * @throws DNSSECException Some other error occurred. - * @return The generated signature - */ -public static RRSIGRecord -sign(RRset rrset, DNSKEYRecord key, PrivateKey privkey, - Date inception, Date expiration, String provider) throws DNSSECException -{ - int alg = key.getAlgorithm(); - checkAlgorithm(privkey, alg); - - RRSIGRecord rrsig = new RRSIGRecord(rrset.getName(), rrset.getDClass(), - rrset.getTTL(), rrset.getType(), - alg, rrset.getTTL(), - expiration, inception, - key.getFootprint(), - key.getName(), null); - - rrsig.setSignature(sign(privkey, key.getPublicKey(), alg, - digestRRset(rrsig, rrset), provider)); - return rrsig; -} - -static SIGRecord -signMessage(Message message, SIGRecord previous, KEYRecord key, - PrivateKey privkey, Date inception, Date expiration) - throws DNSSECException -{ - int alg = key.getAlgorithm(); - checkAlgorithm(privkey, alg); - - SIGRecord sig = new SIGRecord(Name.root, DClass.ANY, 0, 0, - alg, 0, expiration, inception, - key.getFootprint(), - key.getName(), null); - DNSOutput out = new DNSOutput(); - digestSIG(out, sig); - if (previous != null) - out.writeByteArray(previous.getSignature()); - out.writeByteArray(message.toWire()); - - sig.setSignature(sign(privkey, key.getPublicKey(), - alg, out.toByteArray(), null)); - return sig; -} - -static void -verifyMessage(Message message, byte [] bytes, SIGRecord sig, SIGRecord previous, - KEYRecord key) throws DNSSECException -{ - if (message.sig0start == 0) - throw new NoSignatureException(); - - if (!matches(sig, key)) - throw new KeyMismatchException(key, sig); - - Date now = new Date(); - - if (now.compareTo(sig.getExpire()) > 0) - throw new SignatureExpiredException(sig.getExpire(), now); - if (now.compareTo(sig.getTimeSigned()) < 0) - throw new SignatureNotYetValidException(sig.getTimeSigned(), - now); - - DNSOutput out = new DNSOutput(); - digestSIG(out, sig); - if (previous != null) - out.writeByteArray(previous.getSignature()); - - Header header = (Header) message.getHeader().clone(); - header.decCount(Section.ADDITIONAL); - out.writeByteArray(header.toWire()); - - out.writeByteArray(bytes, Header.LENGTH, - message.sig0start - Header.LENGTH); - - verify(key.getPublicKey(), sig.getAlgorithm(), - out.toByteArray(), sig.getSignature()); -} - -/** - * Generate the digest value for a DS key - * @param key Which is covered by the DS record - * @param digestid The type of digest - * @return The digest value as an array of bytes - */ -static byte [] -generateDSDigest(DNSKEYRecord key, int digestid) -{ - MessageDigest digest; - try { - switch (digestid) { - case DSRecord.Digest.SHA1: - digest = MessageDigest.getInstance("sha-1"); - break; - case DSRecord.Digest.SHA256: - digest = MessageDigest.getInstance("sha-256"); - break; - case DSRecord.Digest.GOST3411: - digest = MessageDigest.getInstance("GOST3411"); - break; - case DSRecord.Digest.SHA384: - digest = MessageDigest.getInstance("sha-384"); - break; - default: - throw new IllegalArgumentException( - "unknown DS digest type " + digestid); - } - } - catch (NoSuchAlgorithmException e) { - throw new IllegalStateException("no message digest support"); - } - digest.update(key.getName().toWireCanonical()); - digest.update(key.rdataToWireCanonical()); - return digest.digest(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/DNSSpoofingIPGetter.java b/src/main/java/core/org/xbill/DNS/DNSSpoofingIPGetter.java deleted file mode 100644 index 4a086836..00000000 --- a/src/main/java/core/org/xbill/DNS/DNSSpoofingIPGetter.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.xbill.DNS; - -import packetproxy.gui.GUIOptionPrivateDNS; - -public class DNSSpoofingIPGetter { - private GUIOptionPrivateDNS gui; - public DNSSpoofingIPGetter(GUIOptionPrivateDNS gui){ - this.gui = gui; - } - - public boolean isAuto(){ - return gui.isAutoSpoofing(); - } - - public String get(){ - return gui.getSpoofingIP(); - } - - public String get6(){ - return gui.getSpoofingIP6(); - } - - public String getInt(){ - return gui.getBindInterface(); - } -} diff --git a/src/main/java/core/org/xbill/DNS/DSRecord.java b/src/main/java/core/org/xbill/DNS/DSRecord.java deleted file mode 100644 index 646eec7d..00000000 --- a/src/main/java/core/org/xbill/DNS/DSRecord.java +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) 2002-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import org.xbill.DNS.utils.*; - -/** - * DS - contains a Delegation Signer record, which acts as a - * placeholder for KEY records in the parent zone. - * @see DNSSEC - * - * @author David Blacka - * @author Brian Wellington - */ - -public class DSRecord extends Record { - -public static class Digest { - private Digest() {} - - /** SHA-1 */ - public static final int SHA1 = 1; - - /** SHA-256 */ - public static final int SHA256 = 2; - - /** GOST R 34.11-94 */ - public static final int GOST3411 = 3; - - /** SHA-384 */ - public static final int SHA384 = 4; -} - -public static final int SHA1_DIGEST_ID = Digest.SHA1; -public static final int SHA256_DIGEST_ID = Digest.SHA256; -public static final int GOST3411_DIGEST_ID = Digest.GOST3411; -public static final int SHA384_DIGEST_ID = Digest.SHA384; - -private static final long serialVersionUID = -9001819329700081493L; - -private int footprint; -private int alg; -private int digestid; -private byte [] digest; - -DSRecord() {} - -Record -getObject() { - return new DSRecord(); -} - -/** - * Creates a DS Record from the given data - * @param footprint The original KEY record's footprint (keyid). - * @param alg The original key algorithm. - * @param digestid The digest id code. - * @param digest A hash of the original key. - */ -public -DSRecord(Name name, int dclass, long ttl, int footprint, int alg, - int digestid, byte [] digest) -{ - super(name, Type.DS, dclass, ttl); - this.footprint = checkU16("footprint", footprint); - this.alg = checkU8("alg", alg); - this.digestid = checkU8("digestid", digestid); - this.digest = digest; -} - -/** - * Creates a DS Record from the given data - * @param digestid The digest id code. - * @param key The key to digest - */ -public -DSRecord(Name name, int dclass, long ttl, int digestid, DNSKEYRecord key) -{ - this(name, dclass, ttl, key.getFootprint(), key.getAlgorithm(), - digestid, DNSSEC.generateDSDigest(key, digestid)); -} - -void -rrFromWire(DNSInput in) throws IOException { - footprint = in.readU16(); - alg = in.readU8(); - digestid = in.readU8(); - digest = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - footprint = st.getUInt16(); - alg = st.getUInt8(); - digestid = st.getUInt8(); - digest = st.getHex(); -} - -/** - * Converts rdata to a String - */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(footprint); - sb.append(" "); - sb.append(alg); - sb.append(" "); - sb.append(digestid); - if (digest != null) { - sb.append(" "); - sb.append(base16.toString(digest)); - } - - return sb.toString(); -} - -/** - * Returns the key's algorithm. - */ -public int -getAlgorithm() { - return alg; -} - -/** - * Returns the key's Digest ID. - */ -public int -getDigestID() -{ - return digestid; -} - -/** - * Returns the binary hash of the key. - */ -public byte [] -getDigest() { - return digest; -} - -/** - * Returns the key's footprint. - */ -public int -getFootprint() { - return footprint; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(footprint); - out.writeU8(alg); - out.writeU8(digestid); - if (digest != null) - out.writeByteArray(digest); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/EDNSOption.java b/src/main/java/core/org/xbill/DNS/EDNSOption.java deleted file mode 100644 index 9fccc0e1..00000000 --- a/src/main/java/core/org/xbill/DNS/EDNSOption.java +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) -package org.xbill.DNS; - -import java.io.*; -import java.util.Arrays; - -/** - * DNS extension options, as described in RFC 2671. The rdata of an OPT record - * is defined as a list of options; this represents a single option. - * - * @author Brian Wellington - * @author Ming Zhou <mizhou@bnivideo.com>, Beaumaris Networks - */ -public abstract class EDNSOption { - -public static class Code { - private Code() {} - - /** Name Server Identifier, RFC 5001 */ - public final static int NSID = 3; - - /** Client Subnet, defined in draft-vandergaast-edns-client-subnet-02 */ - public final static int CLIENT_SUBNET = 8; - - private static Mnemonic codes = new Mnemonic("EDNS Option Codes", - Mnemonic.CASE_UPPER); - - static { - codes.setMaximum(0xFFFF); - codes.setPrefix("CODE"); - codes.setNumericAllowed(true); - - codes.add(NSID, "NSID"); - codes.add(CLIENT_SUBNET, "CLIENT_SUBNET"); - } - - /** - * Converts an EDNS Option Code into its textual representation - */ - public static String - string(int code) { - return codes.getText(code); - } - - /** - * Converts a textual representation of an EDNS Option Code into its - * numeric value. - * @param s The textual representation of the option code - * @return The option code, or -1 on error. - */ - public static int - value(String s) { - return codes.getValue(s); - } -} - -private final int code; - -/** - * - * Creates an option with the given option code and data. - */ -public -EDNSOption(int code) { - this.code = Record.checkU16("code", code); -} - -public String -toString() { - StringBuffer sb = new StringBuffer(); - - sb.append("{"); - sb.append(EDNSOption.Code.string(code)); - sb.append(": "); - sb.append(optionToString()); - sb.append("}"); - - return sb.toString(); -} - -/** - * Returns the EDNS Option's code. - * - * @return the option code - */ -public int -getCode() { - return code; -} - -/** - * Returns the EDNS Option's data, as a byte array. - * - * @return the option data - */ -byte [] -getData() { - DNSOutput out = new DNSOutput(); - optionToWire(out); - return out.toByteArray(); -} - -/** - * Converts the wire format of an EDNS Option (the option data only) into the - * type-specific format. - * @param in The input Stream. - */ -abstract void -optionFromWire(DNSInput in) throws IOException; - -/** - * Converts the wire format of an EDNS Option (including code and length) into - * the type-specific format. - * @param out The input stream. - */ -static EDNSOption -fromWire(DNSInput in) throws IOException { - int code, length; - - code = in.readU16(); - length = in.readU16(); - if (in.remaining() < length) - throw new WireParseException("truncated option"); - int save = in.saveActive(); - in.setActive(length); - EDNSOption option; - switch (code) { - case Code.NSID: - option = new NSIDOption(); - break; - case Code.CLIENT_SUBNET: - option = new ClientSubnetOption(); - break; - default: - option = new GenericEDNSOption(code); - break; - } - option.optionFromWire(in); - in.restoreActive(save); - - return option; -} - -/** - * Converts the wire format of an EDNS Option (including code and length) into - * the type-specific format. - * @return The option, in wire format. - */ -public static EDNSOption -fromWire(byte [] b) throws IOException { - return fromWire(new DNSInput(b)); -} - -/** - * Converts an EDNS Option (the type-specific option data only) into wire format. - * @param out The output stream. - */ -abstract void -optionToWire(DNSOutput out); - -/** - * Converts an EDNS Option (including code and length) into wire format. - * @param out The output stream. - */ -void -toWire(DNSOutput out) { - out.writeU16(code); - int lengthPosition = out.current(); - out.writeU16(0); /* until we know better */ - optionToWire(out); - int length = out.current() - lengthPosition - 2; - out.writeU16At(length, lengthPosition); -} - -/** - * Converts an EDNS Option (including code and length) into wire format. - * @return The option, in wire format. - */ -public byte [] -toWire() throws IOException { - DNSOutput out = new DNSOutput(); - toWire(out); - return out.toByteArray(); -} - -/** - * Determines if two EDNS Options are identical. - * @param arg The option to compare to - * @return true if the options are equal, false otherwise. - */ -public boolean -equals(Object arg) { - if (arg == null || !(arg instanceof EDNSOption)) - return false; - EDNSOption opt = (EDNSOption) arg; - if (code != opt.code) - return false; - return Arrays.equals(getData(), opt.getData()); -} - -/** - * Generates a hash code based on the EDNS Option's data. - */ -public int -hashCode() { - byte [] array = getData(); - int hashval = 0; - for (int i = 0; i < array.length; i++) - hashval += ((hashval << 3) + (array[i] & 0xFF)); - return hashval; -} - -abstract String optionToString(); - -} diff --git a/src/main/java/core/org/xbill/DNS/EmptyRecord.java b/src/main/java/core/org/xbill/DNS/EmptyRecord.java deleted file mode 100644 index f5e61e89..00000000 --- a/src/main/java/core/org/xbill/DNS/EmptyRecord.java +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * A class implementing Records with no data; that is, records used in - * the question section of messages and meta-records in dynamic update. - * - * @author Brian Wellington - */ - -class EmptyRecord extends Record { - -private static final long serialVersionUID = 3601852050646429582L; - -EmptyRecord() {} - -Record -getObject() { - return new EmptyRecord(); -} - -void -rrFromWire(DNSInput in) throws IOException { -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { -} - -String -rrToString() { - return ""; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { -} - -} diff --git a/src/main/java/core/org/xbill/DNS/ExtendedFlags.java b/src/main/java/core/org/xbill/DNS/ExtendedFlags.java deleted file mode 100644 index 8f3bbab8..00000000 --- a/src/main/java/core/org/xbill/DNS/ExtendedFlags.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Constants and functions relating to EDNS flags. - * - * @author Brian Wellington - */ - -public final class ExtendedFlags { - -private static Mnemonic extflags = new Mnemonic("EDNS Flag", - Mnemonic.CASE_LOWER); - -/** dnssec ok */ -public static final int DO = 0x8000; - -static { - extflags.setMaximum(0xFFFF); - extflags.setPrefix("FLAG"); - extflags.setNumericAllowed(true); - - extflags.add(DO, "do"); -} - -private -ExtendedFlags() {} - -/** Converts a numeric extended flag into a String */ -public static String -string(int i) { - return extflags.getText(i); -} - -/** - * Converts a textual representation of an extended flag into its numeric - * value - */ -public static int -value(String s) { - return extflags.getValue(s); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/ExtendedResolver.java b/src/main/java/core/org/xbill/DNS/ExtendedResolver.java deleted file mode 100644 index f762b84d..00000000 --- a/src/main/java/core/org/xbill/DNS/ExtendedResolver.java +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.*; -import java.io.*; -import java.net.*; - -/** - * An implementation of Resolver that can send queries to multiple servers, - * sending the queries multiple times if necessary. - * @see Resolver - * - * @author Brian Wellington - */ - -public class ExtendedResolver implements Resolver { - -private static class Resolution implements ResolverListener { - Resolver [] resolvers; - int [] sent; - Object [] inprogress; - int retries; - int outstanding; - boolean done; - Message query; - Message response; - Throwable thrown; - ResolverListener listener; - - public - Resolution(ExtendedResolver eres, Message query) { - List l = eres.resolvers; - resolvers = (Resolver []) l.toArray (new Resolver[l.size()]); - if (eres.loadBalance) { - int nresolvers = resolvers.length; - /* - * Note: this is not synchronized, since the - * worst thing that can happen is a random - * ordering, which is ok. - */ - int start = eres.lbStart++ % nresolvers; - if (eres.lbStart > nresolvers) - eres.lbStart %= nresolvers; - if (start > 0) { - Resolver [] shuffle = new Resolver[nresolvers]; - for (int i = 0; i < nresolvers; i++) { - int pos = (i + start) % nresolvers; - shuffle[i] = resolvers[pos]; - } - resolvers = shuffle; - } - } - sent = new int[resolvers.length]; - inprogress = new Object[resolvers.length]; - retries = eres.retries; - this.query = query; - } - - /* Asynchronously sends a message. */ - public void - send(int n) { - sent[n]++; - outstanding++; - try { - inprogress[n] = resolvers[n].sendAsync(query, this); - } - catch (Throwable t) { - synchronized (this) { - thrown = t; - done = true; - if (listener == null) { - notifyAll(); - return; - } - } - } - } - - /* Start a synchronous resolution */ - public Message - start() throws IOException { - try { - /* - * First, try sending synchronously. If this works, - * we're done. Otherwise, we'll get an exception - * and continue. It would be easier to call send(0), - * but this avoids a thread creation. If and when - * SimpleResolver.sendAsync() can be made to not - * create a thread, this could be changed. - */ - sent[0]++; - outstanding++; - inprogress[0] = new Object(); - return resolvers[0].send(query); - } - catch (Exception e) { - /* - * This will either cause more queries to be sent - * asynchronously or will set the 'done' flag. - */ - handleException(inprogress[0], e); - } - /* - * Wait for a successful response or for each - * subresolver to fail. - */ - synchronized (this) { - while (!done) { - try { - wait(); - } - catch (InterruptedException e) { - } - } - } - /* Return the response or throw an exception */ - if (response != null) - return response; - else if (thrown instanceof IOException) - throw (IOException) thrown; - else if (thrown instanceof RuntimeException) - throw (RuntimeException) thrown; - else if (thrown instanceof Error) - throw (Error) thrown; - else - throw new IllegalStateException - ("ExtendedResolver failure"); - } - - /* Start an asynchronous resolution */ - public void - startAsync(ResolverListener listener) { - this.listener = listener; - send(0); - } - - /* - * Receive a response. If the resolution hasn't been completed, - * either wake up the blocking thread or call the callback. - */ - public void - receiveMessage(Object id, Message m) { - if (Options.check("verbose")) - System.err.println("ExtendedResolver: " + - "received message"); - synchronized (this) { - if (done) - return; - response = m; - done = true; - if (listener == null) { - notifyAll(); - return; - } - } - listener.receiveMessage(this, response); - } - - /* - * Receive an exception. If the resolution has been completed, - * do nothing. Otherwise make progress. - */ - public void - handleException(Object id, Exception e) { - if (Options.check("verbose")) - System.err.println("ExtendedResolver: got " + e); - synchronized (this) { - outstanding--; - if (done) - return; - int n; - for (n = 0; n < inprogress.length; n++) - if (inprogress[n] == id) - break; - /* If we don't know what this is, do nothing. */ - if (n == inprogress.length) - return; - boolean startnext = false; - /* - * If this is the first response from server n, - * we should start sending queries to server n + 1. - */ - if (sent[n] == 1 && n < resolvers.length - 1) - startnext = true; - if (e instanceof InterruptedIOException) { - /* Got a timeout; resend */ - if (sent[n] < retries) - send(n); - if (thrown == null) - thrown = e; - } else if (e instanceof SocketException) { - /* - * Problem with the socket; don't resend - * on it - */ - if (thrown == null || - thrown instanceof InterruptedIOException) - thrown = e; - } else { - /* - * Problem with the response; don't resend - * on the same socket. - */ - thrown = e; - } - if (done) - return; - if (startnext) - send(n + 1); - if (done) - return; - if (outstanding == 0) { - /* - * If we're done and this is synchronous, - * wake up the blocking thread. - */ - done = true; - if (listener == null) { - notifyAll(); - return; - } - } - if (!done) - return; - } - /* If we're done and this is asynchronous, call the callback. */ - if (!(thrown instanceof Exception)) - thrown = new RuntimeException(thrown.getMessage()); - listener.handleException(this, (Exception) thrown); - } -} - -private static final int quantum = 5; - -private List resolvers; -private boolean loadBalance = false; -private int lbStart = 0; -private int retries = 3; - -private void -init() { - resolvers = new ArrayList(); -} - -/** - * Creates a new Extended Resolver. The default ResolverConfig is used to - * determine the servers for which SimpleResolver contexts should be - * initialized. - * @see SimpleResolver - * @see ResolverConfig - * @exception UnknownHostException Failure occured initializing SimpleResolvers - */ -public -ExtendedResolver() throws UnknownHostException { - init(); - String [] servers = ResolverConfig.getCurrentConfig().servers(); - if (servers != null) { - for (int i = 0; i < servers.length; i++) { - Resolver r = new SimpleResolver(servers[i]); - r.setTimeout(quantum); - resolvers.add(r); - } - } - else - resolvers.add(new SimpleResolver()); -} - -/** - * Creates a new Extended Resolver - * @param servers An array of server names for which SimpleResolver - * contexts should be initialized. - * @see SimpleResolver - * @exception UnknownHostException Failure occured initializing SimpleResolvers - */ -public -ExtendedResolver(String [] servers) throws UnknownHostException { - init(); - for (int i = 0; i < servers.length; i++) { - Resolver r = new SimpleResolver(servers[i]); - r.setTimeout(quantum); - resolvers.add(r); - } -} - -/** - * Creates a new Extended Resolver - * @param res An array of pre-initialized Resolvers is provided. - * @see SimpleResolver - * @exception UnknownHostException Failure occured initializing SimpleResolvers - */ -public -ExtendedResolver(Resolver [] res) throws UnknownHostException { - init(); - for (int i = 0; i < res.length; i++) - resolvers.add(res[i]); -} - -public void -setPort(int port) { - for (int i = 0; i < resolvers.size(); i++) - ((Resolver)resolvers.get(i)).setPort(port); -} - -public void -setTCP(boolean flag) { - for (int i = 0; i < resolvers.size(); i++) - ((Resolver)resolvers.get(i)).setTCP(flag); -} - -public void -setIgnoreTruncation(boolean flag) { - for (int i = 0; i < resolvers.size(); i++) - ((Resolver)resolvers.get(i)).setIgnoreTruncation(flag); -} - -public void -setEDNS(int level) { - for (int i = 0; i < resolvers.size(); i++) - ((Resolver)resolvers.get(i)).setEDNS(level); -} - -public void -setEDNS(int level, int payloadSize, int flags, List options) { - for (int i = 0; i < resolvers.size(); i++) - ((Resolver)resolvers.get(i)).setEDNS(level, payloadSize, - flags, options); -} - -public void -setTSIGKey(TSIG key) { - for (int i = 0; i < resolvers.size(); i++) - ((Resolver)resolvers.get(i)).setTSIGKey(key); -} - -public void -setTimeout(int secs, int msecs) { - for (int i = 0; i < resolvers.size(); i++) - ((Resolver)resolvers.get(i)).setTimeout(secs, msecs); -} - -public void -setTimeout(int secs) { - setTimeout(secs, 0); -} - -/** - * Sends a message and waits for a response. Multiple servers are queried, - * and queries are sent multiple times until either a successful response - * is received, or it is clear that there is no successful response. - * @param query The query to send. - * @return The response. - * @throws IOException An error occurred while sending or receiving. - */ -public Message -send(Message query) throws IOException { - Resolution res = new Resolution(this, query); - return res.start(); -} - -/** - * Asynchronously sends a message to multiple servers, potentially multiple - * times, registering a listener to receive a callback on success or exception. - * Multiple asynchronous lookups can be performed in parallel. Since the - * callback may be invoked before the function returns, external - * synchronization is necessary. - * @param query The query to send - * @param listener The object containing the callbacks. - * @return An identifier, which is also a parameter in the callback - */ -public Object -sendAsync(final Message query, final ResolverListener listener) { - Resolution res = new Resolution(this, query); - res.startAsync(listener); - return res; -} - -/** Returns the nth resolver used by this ExtendedResolver */ -public Resolver -getResolver(int n) { - if (n < resolvers.size()) - return (Resolver)resolvers.get(n); - return null; -} - -/** Returns all resolvers used by this ExtendedResolver */ -public Resolver [] -getResolvers() { - return (Resolver []) resolvers.toArray(new Resolver[resolvers.size()]); -} - -/** Adds a new resolver to be used by this ExtendedResolver */ -public void -addResolver(Resolver r) { - resolvers.add(r); -} - -/** Deletes a resolver used by this ExtendedResolver */ -public void -deleteResolver(Resolver r) { - resolvers.remove(r); -} - -/** Sets whether the servers should be load balanced. - * @param flag If true, servers will be tried in round-robin order. If false, - * servers will always be queried in the same order. - */ -public void -setLoadBalance(boolean flag) { - loadBalance = flag; -} - -/** Sets the number of retries sent to each server per query */ -public void -setRetries(int retries) { - this.retries = retries; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Flags.java b/src/main/java/core/org/xbill/DNS/Flags.java deleted file mode 100644 index 964ce23f..00000000 --- a/src/main/java/core/org/xbill/DNS/Flags.java +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Constants and functions relating to flags in the DNS header. - * - * @author Brian Wellington - */ - -public final class Flags { - -private static Mnemonic flags = new Mnemonic("DNS Header Flag", - Mnemonic.CASE_LOWER); - -/** query/response */ -public static final byte QR = 0; - -/** authoritative answer */ -public static final byte AA = 5; - -/** truncated */ -public static final byte TC = 6; - -/** recursion desired */ -public static final byte RD = 7; - -/** recursion available */ -public static final byte RA = 8; - -/** authenticated data */ -public static final byte AD = 10; - -/** (security) checking disabled */ -public static final byte CD = 11; - -/** dnssec ok (extended) */ -public static final int DO = ExtendedFlags.DO; - -static { - flags.setMaximum(0xF); - flags.setPrefix("FLAG"); - flags.setNumericAllowed(true); - - flags.add(QR, "qr"); - flags.add(AA, "aa"); - flags.add(TC, "tc"); - flags.add(RD, "rd"); - flags.add(RA, "ra"); - flags.add(AD, "ad"); - flags.add(CD, "cd"); -} - -private -Flags() {} - -/** Converts a numeric Flag into a String */ -public static String -string(int i) { - return flags.getText(i); -} - -/** Converts a String representation of an Flag into its numeric value */ -public static int -value(String s) { - return flags.getValue(s); -} - -/** - * Indicates if a bit in the flags field is a flag or not. If it's part of - * the rcode or opcode, it's not. - */ -public static boolean -isFlag(int index) { - flags.check(index); - if ((index >= 1 && index <= 4) || (index >= 12)) - return false; - return true; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/FormattedTime.java b/src/main/java/core/org/xbill/DNS/FormattedTime.java deleted file mode 100644 index c76a8462..00000000 --- a/src/main/java/core/org/xbill/DNS/FormattedTime.java +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Routines for converting time values to and from YYYYMMDDHHMMSS format. - * - * @author Brian Wellington - */ - -import java.util.*; -import java.text.*; - -final class FormattedTime { - -private static NumberFormat w2, w4; - -static { - w2 = new DecimalFormat(); - w2.setMinimumIntegerDigits(2); - - w4 = new DecimalFormat(); - w4.setMinimumIntegerDigits(4); - w4.setGroupingUsed(false); -} - -private -FormattedTime() {} - -/** - * Converts a Date into a formatted string. - * @param date The Date to convert. - * @return The formatted string. - */ -public static String -format(Date date) { - Calendar c = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - StringBuffer sb = new StringBuffer(); - - c.setTime(date); - sb.append(w4.format(c.get(Calendar.YEAR))); - sb.append(w2.format(c.get(Calendar.MONTH)+1)); - sb.append(w2.format(c.get(Calendar.DAY_OF_MONTH))); - sb.append(w2.format(c.get(Calendar.HOUR_OF_DAY))); - sb.append(w2.format(c.get(Calendar.MINUTE))); - sb.append(w2.format(c.get(Calendar.SECOND))); - return sb.toString(); -} - -/** - * Parses a formatted time string into a Date. - * @param s The string, in the form YYYYMMDDHHMMSS. - * @return The Date object. - * @throws TextParseExcetption The string was invalid. - */ -public static Date -parse(String s) throws TextParseException { - if (s.length() != 14) { - throw new TextParseException("Invalid time encoding: " + s); - } - - Calendar c = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - c.clear(); - try { - int year = Integer.parseInt(s.substring(0, 4)); - int month = Integer.parseInt(s.substring(4, 6)) - 1; - int date = Integer.parseInt(s.substring(6, 8)); - int hour = Integer.parseInt(s.substring(8, 10)); - int minute = Integer.parseInt(s.substring(10, 12)); - int second = Integer.parseInt(s.substring(12, 14)); - c.set(year, month, date, hour, minute, second); - } - catch (NumberFormatException e) { - throw new TextParseException("Invalid time encoding: " + s); - } - return c.getTime(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/GPOSRecord.java b/src/main/java/core/org/xbill/DNS/GPOSRecord.java deleted file mode 100644 index 688d5675..00000000 --- a/src/main/java/core/org/xbill/DNS/GPOSRecord.java +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * Geographical Location - describes the physical location of a host. - * - * @author Brian Wellington - */ - -public class GPOSRecord extends Record { - -private static final long serialVersionUID = -6349714958085750705L; - -private byte [] latitude, longitude, altitude; - -GPOSRecord() {} - -Record -getObject() { - return new GPOSRecord(); -} - -private void -validate(double longitude, double latitude) throws IllegalArgumentException -{ - if (longitude < -90.0 || longitude > 90.0) { - throw new IllegalArgumentException("illegal longitude " + - longitude); - } - if (latitude < -180.0 || latitude > 180.0) { - throw new IllegalArgumentException("illegal latitude " + - latitude); - } -} - -/** - * Creates an GPOS Record from the given data - * @param longitude The longitude component of the location. - * @param latitude The latitude component of the location. - * @param altitude The altitude component of the location (in meters above sea - * level). -*/ -public -GPOSRecord(Name name, int dclass, long ttl, double longitude, double latitude, - double altitude) -{ - super(name, Type.GPOS, dclass, ttl); - validate(longitude, latitude); - this.longitude = Double.toString(longitude).getBytes(); - this.latitude = Double.toString(latitude).getBytes(); - this.altitude = Double.toString(altitude).getBytes(); -} - -/** - * Creates an GPOS Record from the given data - * @param longitude The longitude component of the location. - * @param latitude The latitude component of the location. - * @param altitude The altitude component of the location (in meters above sea - * level). -*/ -public -GPOSRecord(Name name, int dclass, long ttl, String longitude, String latitude, - String altitude) -{ - super(name, Type.GPOS, dclass, ttl); - try { - this.longitude = byteArrayFromString(longitude); - this.latitude = byteArrayFromString(latitude); - validate(getLongitude(), getLatitude()); - this.altitude = byteArrayFromString(altitude); - } - catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } -} - -void -rrFromWire(DNSInput in) throws IOException { - longitude = in.readCountedString(); - latitude = in.readCountedString(); - altitude = in.readCountedString(); - try { - validate(getLongitude(), getLatitude()); - } - catch(IllegalArgumentException e) { - throw new WireParseException(e.getMessage()); - } -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - try { - longitude = byteArrayFromString(st.getString()); - latitude = byteArrayFromString(st.getString()); - altitude = byteArrayFromString(st.getString()); - } - catch (TextParseException e) { - throw st.exception(e.getMessage()); - } - try { - validate(getLongitude(), getLatitude()); - } - catch(IllegalArgumentException e) { - throw new WireParseException(e.getMessage()); - } -} - -/** Convert to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(byteArrayToString(longitude, true)); - sb.append(" "); - sb.append(byteArrayToString(latitude, true)); - sb.append(" "); - sb.append(byteArrayToString(altitude, true)); - return sb.toString(); -} - -/** Returns the longitude as a string */ -public String -getLongitudeString() { - return byteArrayToString(longitude, false); -} - -/** - * Returns the longitude as a double - * @throws NumberFormatException The string does not contain a valid numeric - * value. - */ -public double -getLongitude() { - return Double.parseDouble(getLongitudeString()); -} - -/** Returns the latitude as a string */ -public String -getLatitudeString() { - return byteArrayToString(latitude, false); -} - -/** - * Returns the latitude as a double - * @throws NumberFormatException The string does not contain a valid numeric - * value. - */ -public double -getLatitude() { - return Double.parseDouble(getLatitudeString()); -} - -/** Returns the altitude as a string */ -public String -getAltitudeString() { - return byteArrayToString(altitude, false); -} - -/** - * Returns the altitude as a double - * @throws NumberFormatException The string does not contain a valid numeric - * value. - */ -public double -getAltitude() { - return Double.parseDouble(getAltitudeString()); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeCountedString(longitude); - out.writeCountedString(latitude); - out.writeCountedString(altitude); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Generator.java b/src/main/java/core/org/xbill/DNS/Generator.java deleted file mode 100644 index a08d3435..00000000 --- a/src/main/java/core/org/xbill/DNS/Generator.java +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; - -/** - * A representation of a $GENERATE statement in a master file. - * - * @author Brian Wellington - */ - -public class Generator { - -/** The start of the range. */ -public long start; - -/** The end of the range. */ -public long end; - -/** The step value of the range. */ -public long step; - -/** The pattern to use for generating record names. */ -public final String namePattern; - -/** The type of the generated records. */ -public final int type; - -/** The class of the generated records. */ -public final int dclass; - -/** The ttl of the generated records. */ -public final long ttl; - -/** The pattern to use for generating record data. */ -public final String rdataPattern; - -/** The origin to append to relative names. */ -public final Name origin; - -private long current; - -/** - * Indicates whether generation is supported for this type. - * @throws InvalidTypeException The type is out of range. - */ -public static boolean -supportedType(int type) { - Type.check(type); - return (type == Type.PTR || type == Type.CNAME || type == Type.DNAME || - type == Type.A || type == Type.AAAA || type == Type.NS); -} - -/** - * Creates a specification for generating records, as a $GENERATE - * statement in a master file. - * @param start The start of the range. - * @param end The end of the range. - * @param step The step value of the range. - * @param namePattern The pattern to use for generating record names. - * @param type The type of the generated records. The supported types are - * PTR, CNAME, DNAME, A, AAAA, and NS. - * @param dclass The class of the generated records. - * @param ttl The ttl of the generated records. - * @param rdataPattern The pattern to use for generating record data. - * @param origin The origin to append to relative names. - * @throws IllegalArgumentException The range is invalid. - * @throws IllegalArgumentException The type does not support generation. - * @throws IllegalArgumentException The dclass is not a valid class. - */ -public -Generator(long start, long end, long step, String namePattern, - int type, int dclass, long ttl, String rdataPattern, Name origin) -{ - if (start < 0 || end < 0 || start > end || step <= 0) - throw new IllegalArgumentException - ("invalid range specification"); - if (!supportedType(type)) - throw new IllegalArgumentException("unsupported type"); - DClass.check(dclass); - - this.start = start; - this.end = end; - this.step = step; - this.namePattern = namePattern; - this.type = type; - this.dclass = dclass; - this.ttl = ttl; - this.rdataPattern = rdataPattern; - this.origin = origin; - this.current = start; -} - -private String -substitute(String spec, long n) throws IOException { - boolean escaped = false; - byte [] str = spec.getBytes(); - StringBuffer sb = new StringBuffer(); - - for (int i = 0; i < str.length; i++) { - char c = (char)(str[i] & 0xFF); - if (escaped) { - sb.append(c); - escaped = false; - } else if (c == '\\') { - if (i + 1 == str.length) - throw new TextParseException - ("invalid escape character"); - escaped = true; - } else if (c == '$') { - boolean negative = false; - long offset = 0; - long width = 0; - long base = 10; - boolean wantUpperCase = false; - if (i + 1 < str.length && str[i + 1] == '$') { - // '$$' == literal '$' for backwards - // compatibility with old versions of BIND. - c = (char)(str[++i] & 0xFF); - sb.append(c); - continue; - } else if (i + 1 < str.length && str[i + 1] == '{') { - // It's a substitution with modifiers. - i++; - if (i + 1 < str.length && str[i + 1] == '-') { - negative = true; - i++; - } - while (i + 1 < str.length) { - c = (char)(str[++i] & 0xFF); - if (c == ',' || c == '}') - break; - if (c < '0' || c > '9') - throw new TextParseException( - "invalid offset"); - c -= '0'; - offset *= 10; - offset += c; - } - if (negative) - offset = -offset; - - if (c == ',') { - while (i + 1 < str.length) { - c = (char)(str[++i] & 0xFF); - if (c == ',' || c == '}') - break; - if (c < '0' || c > '9') - throw new - TextParseException( - "invalid width"); - c -= '0'; - width *= 10; - width += c; - } - } - - if (c == ',') { - if (i + 1 == str.length) - throw new TextParseException( - "invalid base"); - c = (char)(str[++i] & 0xFF); - if (c == 'o') - base = 8; - else if (c == 'x') - base = 16; - else if (c == 'X') { - base = 16; - wantUpperCase = true; - } - else if (c != 'd') - throw new TextParseException( - "invalid base"); - } - - if (i + 1 == str.length || str[i + 1] != '}') - throw new TextParseException - ("invalid modifiers"); - i++; - } - long v = n + offset; - if (v < 0) - throw new TextParseException - ("invalid offset expansion"); - String number; - if (base == 8) - number = Long.toOctalString(v); - else if (base == 16) - number = Long.toHexString(v); - else - number = Long.toString(v); - if (wantUpperCase) - number = number.toUpperCase(); - if (width != 0 && width > number.length()) { - int zeros = (int)width - number.length(); - while (zeros-- > 0) - sb.append('0'); - } - sb.append(number); - } else { - sb.append(c); - } - } - return sb.toString(); -} - -/** - * Constructs and returns the next record in the expansion. - * @throws IOException The name or rdata was invalid after substitutions were - * performed. - */ -public Record -nextRecord() throws IOException { - if (current > end) - return null; - String namestr = substitute(namePattern, current); - Name name = Name.fromString(namestr, origin); - String rdata = substitute(rdataPattern, current); - current += step; - return Record.fromString(name, type, dclass, ttl, rdata, origin); -} - -/** - * Constructs and returns all records in the expansion. - * @throws IOException The name or rdata of a record was invalid after - * substitutions were performed. - */ -public Record [] -expand() throws IOException { - List list = new ArrayList(); - for (long i = start; i < end; i += step) { - String namestr = substitute(namePattern, current); - Name name = Name.fromString(namestr, origin); - String rdata = substitute(rdataPattern, current); - list.add(Record.fromString(name, type, dclass, ttl, - rdata, origin)); - } - return (Record []) list.toArray(new Record[list.size()]); -} - -/** - * Converts the generate specification to a string containing the corresponding - * $GENERATE statement. - */ -public String -toString() { - StringBuffer sb = new StringBuffer(); - sb.append("$GENERATE "); - sb.append(start + "-" + end); - if (step > 1) - sb.append("/" + step); - sb.append(" "); - sb.append(namePattern + " "); - sb.append(ttl + " "); - if (dclass != DClass.IN || !Options.check("noPrintIN")) - sb.append(DClass.string(dclass) + " "); - sb.append(Type.string(type) + " "); - sb.append(rdataPattern + " "); - return sb.toString(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/GenericEDNSOption.java b/src/main/java/core/org/xbill/DNS/GenericEDNSOption.java deleted file mode 100644 index 7c8b51b0..00000000 --- a/src/main/java/core/org/xbill/DNS/GenericEDNSOption.java +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) -package org.xbill.DNS; - -import java.io.*; - -import org.xbill.DNS.utils.base16; - -/** - * An EDNSOption with no internal structure. - * - * @author Ming Zhou <mizhou@bnivideo.com>, Beaumaris Networks - * @author Brian Wellington - */ -public class GenericEDNSOption extends EDNSOption { - -private byte [] data; - -GenericEDNSOption(int code) { - super(code); -} - -/** - * Construct a generic EDNS option. - * @param data The contents of the option. - */ -public -GenericEDNSOption(int code, byte [] data) { - super(code); - this.data = Record.checkByteArrayLength("option data", data, 0xFFFF); -} - -void -optionFromWire(DNSInput in) throws IOException { - data = in.readByteArray(); -} - -void -optionToWire(DNSOutput out) { - out.writeByteArray(data); -} - -String -optionToString() { - return "<" + base16.toString(data) + ">"; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/HINFORecord.java b/src/main/java/core/org/xbill/DNS/HINFORecord.java deleted file mode 100644 index 18fed32d..00000000 --- a/src/main/java/core/org/xbill/DNS/HINFORecord.java +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * Host Information - describes the CPU and OS of a host - * - * @author Brian Wellington - */ - -public class HINFORecord extends Record { - -private static final long serialVersionUID = -4732870630947452112L; - -private byte [] cpu, os; - -HINFORecord() {} - -Record -getObject() { - return new HINFORecord(); -} - -/** - * Creates an HINFO Record from the given data - * @param cpu A string describing the host's CPU - * @param os A string describing the host's OS - * @throws IllegalArgumentException One of the strings has invalid escapes - */ -public -HINFORecord(Name name, int dclass, long ttl, String cpu, String os) { - super(name, Type.HINFO, dclass, ttl); - try { - this.cpu = byteArrayFromString(cpu); - this.os = byteArrayFromString(os); - } - catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } -} - -void -rrFromWire(DNSInput in) throws IOException { - cpu = in.readCountedString(); - os = in.readCountedString(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - try { - cpu = byteArrayFromString(st.getString()); - os = byteArrayFromString(st.getString()); - } - catch (TextParseException e) { - throw st.exception(e.getMessage()); - } -} - -/** - * Returns the host's CPU - */ -public String -getCPU() { - return byteArrayToString(cpu, false); -} - -/** - * Returns the host's OS - */ -public String -getOS() { - return byteArrayToString(os, false); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeCountedString(cpu); - out.writeCountedString(os); -} - -/** - * Converts to a string - */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(byteArrayToString(cpu, true)); - sb.append(" "); - sb.append(byteArrayToString(os, true)); - return sb.toString(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/HTTPSRecord.java b/src/main/java/core/org/xbill/DNS/HTTPSRecord.java deleted file mode 100644 index b53e101b..00000000 --- a/src/main/java/core/org/xbill/DNS/HTTPSRecord.java +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -package org.xbill.DNS; - -import java.util.List; - -/** - * HTTPS Service Location and Parameter Binding Record - * - * @see draft-ietf-dnsop-svcb-https - */ -public class HTTPSRecord extends SVCBBase { - HTTPSRecord() {} - - public HTTPSRecord( - Name name, int dclass, long ttl, int priority, Name domain, List params) { - super(name, Type.HTTPS, dclass, ttl, priority, domain, params); - } - - Record getObject() { - return new HTTPSRecord(); - } -} \ No newline at end of file diff --git a/src/main/java/core/org/xbill/DNS/Header.java b/src/main/java/core/org/xbill/DNS/Header.java deleted file mode 100644 index 0b997128..00000000 --- a/src/main/java/core/org/xbill/DNS/Header.java +++ /dev/null @@ -1,300 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; - -/** - * A DNS message header - * @see Message - * - * @author Brian Wellington - */ - -public class Header implements Cloneable { - -private int id; -private int flags; -private int [] counts; - -private static Random random = new Random(); - -/** The length of a DNS Header in wire format. */ -public static final int LENGTH = 12; - -private void -init() { - counts = new int[4]; - flags = 0; - id = -1; -} - -/** - * Create a new empty header. - * @param id The message id - */ -public -Header(int id) { - init(); - setID(id); -} - -/** - * Create a new empty header with a random message id - */ -public -Header() { - init(); -} - -/** - * Parses a Header from a stream containing DNS wire format. - */ -Header(DNSInput in) throws IOException { - this(in.readU16()); - flags = in.readU16(); - for (int i = 0; i < counts.length; i++) - counts[i] = in.readU16(); -} - -/** - * Creates a new Header from its DNS wire format representation - * @param b A byte array containing the DNS Header. - */ -public -Header(byte [] b) throws IOException { - this(new DNSInput(b)); -} - -void -toWire(DNSOutput out) { - out.writeU16(getID()); - out.writeU16(flags); - for (int i = 0; i < counts.length; i++) - out.writeU16(counts[i]); -} - -public byte [] -toWire() { - DNSOutput out = new DNSOutput(); - toWire(out); - return out.toByteArray(); -} - -static private boolean -validFlag(int bit) { - return (bit >= 0 && bit <= 0xF && Flags.isFlag(bit)); -} - -static private void -checkFlag(int bit) { - if (!validFlag(bit)) - throw new IllegalArgumentException("invalid flag bit " + bit); -} - -static int -setFlag(int flags, int bit, boolean value) { - checkFlag(bit); - - // bits are indexed from left to right - if (value) - return flags |= (1 << (15 - bit)); - else - return flags &= ~(1 << (15 - bit)); -} - -/** - * Sets a flag to the supplied value - * @see Flags - */ -public void -setFlag(int bit) { - checkFlag(bit); - flags = setFlag(flags, bit, true); -} - -/** - * Sets a flag to the supplied value - * @see Flags - */ -public void -unsetFlag(int bit) { - checkFlag(bit); - flags = setFlag(flags, bit, false); -} - -/** - * Retrieves a flag - * @see Flags - */ -public boolean -getFlag(int bit) { - checkFlag(bit); - // bits are indexed from left to right - return (flags & (1 << (15 - bit))) != 0; -} - -boolean [] -getFlags() { - boolean [] array = new boolean[16]; - for (int i = 0; i < array.length; i++) - if (validFlag(i)) - array[i] = getFlag(i); - return array; -} - -/** - * Retrieves the message ID - */ -public int -getID() { - if (id >= 0) - return id; - synchronized (this) { - if (id < 0) - id = random.nextInt(0xffff); - return id; - } -} - -/** - * Sets the message ID - */ -public void -setID(int id) { - if (id < 0 || id > 0xffff) - throw new IllegalArgumentException("DNS message ID " + id + - " is out of range"); - this.id = id; -} - -/** - * Sets the message's rcode - * @see Rcode - */ -public void -setRcode(int value) { - if (value < 0 || value > 0xF) - throw new IllegalArgumentException("DNS Rcode " + value + - " is out of range"); - flags &= ~0xF; - flags |= value; -} - -/** - * Retrieves the mesasge's rcode - * @see Rcode - */ -public int -getRcode() { - return flags & 0xF; -} - -/** - * Sets the message's opcode - * @see Opcode - */ -public void -setOpcode(int value) { - if (value < 0 || value > 0xF) - throw new IllegalArgumentException("DNS Opcode " + value + - "is out of range"); - flags &= 0x87FF; - flags |= (value << 11); -} - -/** - * Retrieves the mesasge's opcode - * @see Opcode - */ -public int -getOpcode() { - return (flags >> 11) & 0xF; -} - -void -setCount(int field, int value) { - if (value < 0 || value > 0xFFFF) - throw new IllegalArgumentException("DNS section count " + - value + " is out of range"); - counts[field] = value; -} - -void -incCount(int field) { - if (counts[field] == 0xFFFF) - throw new IllegalStateException("DNS section count cannot " + - "be incremented"); - counts[field]++; -} - -void -decCount(int field) { - if (counts[field] == 0) - throw new IllegalStateException("DNS section count cannot " + - "be decremented"); - counts[field]--; -} - -/** - * Retrieves the record count for the given section - * @see Section - */ -public int -getCount(int field) { - return counts[field]; -} - -int -getFlagsByte() { - return flags; -} - -/** Converts the header's flags into a String */ -public String -printFlags() { - StringBuffer sb = new StringBuffer(); - - for (int i = 0; i < 16; i++) - if (validFlag(i) && getFlag(i)) { - sb.append(Flags.string(i)); - sb.append(" "); - } - return sb.toString(); -} - -String -toStringWithRcode(int newrcode) { - StringBuffer sb = new StringBuffer(); - - sb.append(";; ->>HEADER<<- "); - sb.append("opcode: " + Opcode.string(getOpcode())); - sb.append(", status: " + Rcode.string(newrcode)); - sb.append(", id: " + getID()); - sb.append("\n"); - - sb.append(";; flags: " + printFlags()); - sb.append("; "); - for (int i = 0; i < 4; i++) - sb.append(Section.string(i) + ": " + getCount(i) + " "); - return sb.toString(); -} - -/** Converts the header into a String */ -public String -toString() { - return toStringWithRcode(getRcode()); -} - -/* Creates a new Header identical to the current one */ -public Object -clone() { - Header h = new Header(); - h.id = id; - h.flags = flags; - System.arraycopy(counts, 0, h.counts, 0, counts.length); - return h; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/IPSECKEYRecord.java b/src/main/java/core/org/xbill/DNS/IPSECKEYRecord.java deleted file mode 100644 index 7eb29560..00000000 --- a/src/main/java/core/org/xbill/DNS/IPSECKEYRecord.java +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.net.*; -import org.xbill.DNS.utils.*; - -/** - * IPsec Keying Material (RFC 4025) - * - * @author Brian Wellington - */ - -public class IPSECKEYRecord extends Record { - -private static final long serialVersionUID = 3050449702765909687L; - -public static class Algorithm { - private Algorithm() {} - - public static final int DSA = 1; - public static final int RSA = 2; -} - -public static class Gateway { - private Gateway() {} - - public static final int None = 0; - public static final int IPv4 = 1; - public static final int IPv6 = 2; - public static final int Name = 3; -} - -private int precedence; -private int gatewayType; -private int algorithmType; -private Object gateway; -private byte [] key; - -IPSECKEYRecord() {} - -Record -getObject() { - return new IPSECKEYRecord(); -} - -/** - * Creates an IPSECKEY Record from the given data. - * @param precedence The record's precedence. - * @param gatewayType The record's gateway type. - * @param algorithmType The record's algorithm type. - * @param gateway The record's gateway. - * @param key The record's public key. - */ -public -IPSECKEYRecord(Name name, int dclass, long ttl, int precedence, - int gatewayType, int algorithmType, Object gateway, - byte [] key) -{ - super(name, Type.IPSECKEY, dclass, ttl); - this.precedence = checkU8("precedence", precedence); - this.gatewayType = checkU8("gatewayType", gatewayType); - this.algorithmType = checkU8("algorithmType", algorithmType); - switch (gatewayType) { - case Gateway.None: - this.gateway = null; - break; - case Gateway.IPv4: - if (!(gateway instanceof InetAddress)) - throw new IllegalArgumentException("\"gateway\" " + - "must be an IPv4 " + - "address"); - this.gateway = gateway; - break; - case Gateway.IPv6: - if (!(gateway instanceof Inet6Address)) - throw new IllegalArgumentException("\"gateway\" " + - "must be an IPv6 " + - "address"); - this.gateway = gateway; - break; - case Gateway.Name: - if (!(gateway instanceof Name)) - throw new IllegalArgumentException("\"gateway\" " + - "must be a DNS " + - "name"); - this.gateway = checkName("gateway", (Name) gateway); - break; - default: - throw new IllegalArgumentException("\"gatewayType\" " + - "must be between 0 and 3"); - } - - this.key = key; -} - -void -rrFromWire(DNSInput in) throws IOException { - precedence = in.readU8(); - gatewayType = in.readU8(); - algorithmType = in.readU8(); - switch (gatewayType) { - case Gateway.None: - gateway = null; - break; - case Gateway.IPv4: - gateway = InetAddress.getByAddress(in.readByteArray(4)); - break; - case Gateway.IPv6: - gateway = InetAddress.getByAddress(in.readByteArray(16)); - break; - case Gateway.Name: - gateway = new Name(in); - break; - default: - throw new WireParseException("invalid gateway type"); - } - if (in.remaining() > 0) - key = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - precedence = st.getUInt8(); - gatewayType = st.getUInt8(); - algorithmType = st.getUInt8(); - switch (gatewayType) { - case Gateway.None: - String s = st.getString(); - if (!s.equals(".")) - throw new TextParseException("invalid gateway format"); - gateway = null; - break; - case Gateway.IPv4: - gateway = st.getAddress(Address.IPv4); - break; - case Gateway.IPv6: - gateway = st.getAddress(Address.IPv6); - break; - case Gateway.Name: - gateway = st.getName(origin); - break; - default: - throw new WireParseException("invalid gateway type"); - } - key = st.getBase64(false); -} - -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(precedence); - sb.append(" "); - sb.append(gatewayType); - sb.append(" "); - sb.append(algorithmType); - sb.append(" "); - switch (gatewayType) { - case Gateway.None: - sb.append("."); - break; - case Gateway.IPv4: - case Gateway.IPv6: - InetAddress gatewayAddr = (InetAddress) gateway; - sb.append(gatewayAddr.getHostAddress()); - break; - case Gateway.Name: - sb.append(gateway); - break; - } - if (key != null) { - sb.append(" "); - sb.append(base64.toString(key)); - } - return sb.toString(); -} - -/** Returns the record's precedence. */ -public int -getPrecedence() { - return precedence; -} - -/** Returns the record's gateway type. */ -public int -getGatewayType() { - return gatewayType; -} - -/** Returns the record's algorithm type. */ -public int -getAlgorithmType() { - return algorithmType; -} - -/** Returns the record's gateway. */ -public Object -getGateway() { - return gateway; -} - -/** Returns the record's public key */ -public byte [] -getKey() { - return key; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU8(precedence); - out.writeU8(gatewayType); - out.writeU8(algorithmType); - switch (gatewayType) { - case Gateway.None: - break; - case Gateway.IPv4: - case Gateway.IPv6: - InetAddress gatewayAddr = (InetAddress) gateway; - out.writeByteArray(gatewayAddr.getAddress()); - break; - case Gateway.Name: - Name gatewayName = (Name) gateway; - gatewayName.toWire(out, null, canonical); - break; - } - if (key != null) - out.writeByteArray(key); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/ISDNRecord.java b/src/main/java/core/org/xbill/DNS/ISDNRecord.java deleted file mode 100644 index 8f9b629c..00000000 --- a/src/main/java/core/org/xbill/DNS/ISDNRecord.java +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * ISDN - identifies the ISDN number and subaddress associated with a name. - * - * @author Brian Wellington - */ - -public class ISDNRecord extends Record { - -private static final long serialVersionUID = -8730801385178968798L; - -private byte [] address; -private byte [] subAddress; - -ISDNRecord() {} - -Record -getObject() { - return new ISDNRecord(); -} - -/** - * Creates an ISDN Record from the given data - * @param address The ISDN number associated with the domain. - * @param subAddress The subaddress, if any. - * @throws IllegalArgumentException One of the strings is invalid. - */ -public -ISDNRecord(Name name, int dclass, long ttl, String address, String subAddress) { - super(name, Type.ISDN, dclass, ttl); - try { - this.address = byteArrayFromString(address); - if (subAddress != null) - this.subAddress = byteArrayFromString(subAddress); - } - catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } -} - -void -rrFromWire(DNSInput in) throws IOException { - address = in.readCountedString(); - if (in.remaining() > 0) - subAddress = in.readCountedString(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - try { - address = byteArrayFromString(st.getString()); - Tokenizer.Token t = st.get(); - if (t.isString()) { - subAddress = byteArrayFromString(t.value); - } else { - st.unget(); - } - } - catch (TextParseException e) { - throw st.exception(e.getMessage()); - } -} - -/** - * Returns the ISDN number associated with the domain. - */ -public String -getAddress() { - return byteArrayToString(address, false); -} - -/** - * Returns the ISDN subaddress, or null if there is none. - */ -public String -getSubAddress() { - if (subAddress == null) - return null; - return byteArrayToString(subAddress, false); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeCountedString(address); - if (subAddress != null) - out.writeCountedString(subAddress); -} - -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(byteArrayToString(address, true)); - if (subAddress != null) { - sb.append(" "); - sb.append(byteArrayToString(subAddress, true)); - } - return sb.toString(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/InvalidDClassException.java b/src/main/java/core/org/xbill/DNS/InvalidDClassException.java deleted file mode 100644 index 6c95cd4b..00000000 --- a/src/main/java/core/org/xbill/DNS/InvalidDClassException.java +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * An exception thrown when an invalid dclass code is specified. - * - * @author Brian Wellington - */ - -public class InvalidDClassException extends IllegalArgumentException { - -public -InvalidDClassException(int dclass) { - super("Invalid DNS class: " + dclass); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/InvalidTTLException.java b/src/main/java/core/org/xbill/DNS/InvalidTTLException.java deleted file mode 100644 index 95776fe9..00000000 --- a/src/main/java/core/org/xbill/DNS/InvalidTTLException.java +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * An exception thrown when an invalid TTL is specified. - * - * @author Brian Wellington - */ - -public class InvalidTTLException extends IllegalArgumentException { - -public -InvalidTTLException(long ttl) { - super("Invalid DNS TTL: " + ttl); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/InvalidTypeException.java b/src/main/java/core/org/xbill/DNS/InvalidTypeException.java deleted file mode 100644 index 7c612766..00000000 --- a/src/main/java/core/org/xbill/DNS/InvalidTypeException.java +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * An exception thrown when an invalid type code is specified. - * - * @author Brian Wellington - */ - -public class InvalidTypeException extends IllegalArgumentException { - -public -InvalidTypeException(int type) { - super("Invalid DNS type: " + type); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/KEYBase.java b/src/main/java/core/org/xbill/DNS/KEYBase.java deleted file mode 100644 index 59a2c6c0..00000000 --- a/src/main/java/core/org/xbill/DNS/KEYBase.java +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.security.PublicKey; - -import org.xbill.DNS.utils.*; - -/** - * The base class for KEY/DNSKEY records, which have identical formats - * - * @author Brian Wellington - */ - -abstract class KEYBase extends Record { - -private static final long serialVersionUID = 3469321722693285454L; - -protected int flags, proto, alg; -protected byte [] key; -protected int footprint = -1; -protected PublicKey publicKey = null; - -protected -KEYBase() {} - -public -KEYBase(Name name, int type, int dclass, long ttl, int flags, int proto, - int alg, byte [] key) -{ - super(name, type, dclass, ttl); - this.flags = checkU16("flags", flags); - this.proto = checkU8("proto", proto); - this.alg = checkU8("alg", alg); - this.key = key; -} - -void -rrFromWire(DNSInput in) throws IOException { - flags = in.readU16(); - proto = in.readU8(); - alg = in.readU8(); - if (in.remaining() > 0) - key = in.readByteArray(); -} - -/** Converts the DNSKEY/KEY Record to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(flags); - sb.append(" "); - sb.append(proto); - sb.append(" "); - sb.append(alg); - if (key != null) { - if (Options.check("multiline")) { - sb.append(" (\n"); - sb.append(base64.formatString(key, 64, "\t", true)); - sb.append(" ; key_tag = "); - sb.append(getFootprint()); - } else { - sb.append(" "); - sb.append(base64.toString(key)); - } - } - return sb.toString(); -} - -/** - * Returns the flags describing the key's properties - */ -public int -getFlags() { - return flags; -} - -/** - * Returns the protocol that the key was created for - */ -public int -getProtocol() { - return proto; -} - -/** - * Returns the key's algorithm - */ -public int -getAlgorithm() { - return alg; -} - -/** - * Returns the binary data representing the key - */ -public byte [] -getKey() { - return key; -} - -/** - * Returns the key's footprint (after computing it) - */ -public int -getFootprint() { - if (footprint >= 0) - return footprint; - - int foot = 0; - - DNSOutput out = new DNSOutput(); - rrToWire(out, null, false); - byte [] rdata = out.toByteArray(); - - if (alg == DNSSEC.Algorithm.RSAMD5) { - int d1 = rdata[rdata.length - 3] & 0xFF; - int d2 = rdata[rdata.length - 2] & 0xFF; - foot = (d1 << 8) + d2; - } - else { - int i; - for (i = 0; i < rdata.length - 1; i += 2) { - int d1 = rdata[i] & 0xFF; - int d2 = rdata[i + 1] & 0xFF; - foot += ((d1 << 8) + d2); - } - if (i < rdata.length) { - int d1 = rdata[i] & 0xFF; - foot += (d1 << 8); - } - foot += ((foot >> 16) & 0xFFFF); - } - footprint = (foot & 0xFFFF); - return footprint; -} - -/** - * Returns a PublicKey corresponding to the data in this key. - * @throws DNSSEC.DNSSECException The key could not be converted. - */ -public PublicKey -getPublicKey() throws DNSSEC.DNSSECException { - if (publicKey != null) - return publicKey; - - publicKey = DNSSEC.toPublicKey(this); - return publicKey; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(flags); - out.writeU8(proto); - out.writeU8(alg); - if (key != null) - out.writeByteArray(key); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/KEYRecord.java b/src/main/java/core/org/xbill/DNS/KEYRecord.java deleted file mode 100644 index 3d2e01cb..00000000 --- a/src/main/java/core/org/xbill/DNS/KEYRecord.java +++ /dev/null @@ -1,352 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.security.PublicKey; -import java.util.*; - -/** - * Key - contains a cryptographic public key. The data can be converted - * to objects implementing java.security.interfaces.PublicKey - * @see DNSSEC - * - * @author Brian Wellington - */ - -public class KEYRecord extends KEYBase { - -private static final long serialVersionUID = 6385613447571488906L; - -public static class Protocol { - /** - * KEY protocol identifiers. - */ - - private Protocol() {} - - /** No defined protocol. */ - public static final int NONE = 0; - - /** Transaction Level Security */ - public static final int TLS = 1; - - /** Email */ - public static final int EMAIL = 2; - - /** DNSSEC */ - public static final int DNSSEC = 3; - - /** IPSEC Control */ - public static final int IPSEC = 4; - - /** Any protocol */ - public static final int ANY = 255; - - private static Mnemonic protocols = new Mnemonic("KEY protocol", - Mnemonic.CASE_UPPER); - - static { - protocols.setMaximum(0xFF); - protocols.setNumericAllowed(true); - - protocols.add(NONE, "NONE"); - protocols.add(TLS, "TLS"); - protocols.add(EMAIL, "EMAIL"); - protocols.add(DNSSEC, "DNSSEC"); - protocols.add(IPSEC, "IPSEC"); - protocols.add(ANY, "ANY"); - } - - /** - * Converts an KEY protocol value into its textual representation - */ - public static String - string(int type) { - return protocols.getText(type); - } - - /** - * Converts a textual representation of a KEY protocol into its - * numeric code. Integers in the range 0..255 are also accepted. - * @param s The textual representation of the protocol - * @return The protocol code, or -1 on error. - */ - public static int - value(String s) { - return protocols.getValue(s); - } -} - -public static class Flags { - /** - * KEY flags identifiers. - */ - - private Flags() {} - - /** KEY cannot be used for confidentiality */ - public static final int NOCONF = 0x4000; - - /** KEY cannot be used for authentication */ - public static final int NOAUTH = 0x8000; - - /** No key present */ - public static final int NOKEY = 0xC000; - - /** Bitmask of the use fields */ - public static final int USE_MASK = 0xC000; - - /** Flag 2 (unused) */ - public static final int FLAG2 = 0x2000; - - /** Flags extension */ - public static final int EXTEND = 0x1000; - - /** Flag 4 (unused) */ - public static final int FLAG4 = 0x0800; - - /** Flag 5 (unused) */ - public static final int FLAG5 = 0x0400; - - /** Key is owned by a user. */ - public static final int USER = 0x0000; - - /** Key is owned by a zone. */ - public static final int ZONE = 0x0100; - - /** Key is owned by a host. */ - public static final int HOST = 0x0200; - - /** Key owner type 3 (reserved). */ - public static final int NTYP3 = 0x0300; - - /** Key owner bitmask. */ - public static final int OWNER_MASK = 0x0300; - - /** Flag 8 (unused) */ - public static final int FLAG8 = 0x0080; - - /** Flag 9 (unused) */ - public static final int FLAG9 = 0x0040; - - /** Flag 10 (unused) */ - public static final int FLAG10 = 0x0020; - - /** Flag 11 (unused) */ - public static final int FLAG11 = 0x0010; - - /** Signatory value 0 */ - public static final int SIG0 = 0; - - /** Signatory value 1 */ - public static final int SIG1 = 1; - - /** Signatory value 2 */ - public static final int SIG2 = 2; - - /** Signatory value 3 */ - public static final int SIG3 = 3; - - /** Signatory value 4 */ - public static final int SIG4 = 4; - - /** Signatory value 5 */ - public static final int SIG5 = 5; - - /** Signatory value 6 */ - public static final int SIG6 = 6; - - /** Signatory value 7 */ - public static final int SIG7 = 7; - - /** Signatory value 8 */ - public static final int SIG8 = 8; - - /** Signatory value 9 */ - public static final int SIG9 = 9; - - /** Signatory value 10 */ - public static final int SIG10 = 10; - - /** Signatory value 11 */ - public static final int SIG11 = 11; - - /** Signatory value 12 */ - public static final int SIG12 = 12; - - /** Signatory value 13 */ - public static final int SIG13 = 13; - - /** Signatory value 14 */ - public static final int SIG14 = 14; - - /** Signatory value 15 */ - public static final int SIG15 = 15; - - private static Mnemonic flags = new Mnemonic("KEY flags", - Mnemonic.CASE_UPPER); - - static { - flags.setMaximum(0xFFFF); - flags.setNumericAllowed(false); - - flags.add(NOCONF, "NOCONF"); - flags.add(NOAUTH, "NOAUTH"); - flags.add(NOKEY, "NOKEY"); - flags.add(FLAG2, "FLAG2"); - flags.add(EXTEND, "EXTEND"); - flags.add(FLAG4, "FLAG4"); - flags.add(FLAG5, "FLAG5"); - flags.add(USER, "USER"); - flags.add(ZONE, "ZONE"); - flags.add(HOST, "HOST"); - flags.add(NTYP3, "NTYP3"); - flags.add(FLAG8, "FLAG8"); - flags.add(FLAG9, "FLAG9"); - flags.add(FLAG10, "FLAG10"); - flags.add(FLAG11, "FLAG11"); - flags.add(SIG0, "SIG0"); - flags.add(SIG1, "SIG1"); - flags.add(SIG2, "SIG2"); - flags.add(SIG3, "SIG3"); - flags.add(SIG4, "SIG4"); - flags.add(SIG5, "SIG5"); - flags.add(SIG6, "SIG6"); - flags.add(SIG7, "SIG7"); - flags.add(SIG8, "SIG8"); - flags.add(SIG9, "SIG9"); - flags.add(SIG10, "SIG10"); - flags.add(SIG11, "SIG11"); - flags.add(SIG12, "SIG12"); - flags.add(SIG13, "SIG13"); - flags.add(SIG14, "SIG14"); - flags.add(SIG15, "SIG15"); - } - - /** - * Converts a textual representation of KEY flags into its - * numeric code. Integers in the range 0..65535 are also accepted. - * @param s The textual representation of the protocol - * @return The protocol code, or -1 on error. - */ - public static int - value(String s) { - int value; - try { - value = Integer.parseInt(s); - if (value >= 0 && value <= 0xFFFF) { - return value; - } - return -1; - } catch (NumberFormatException e) { - } - StringTokenizer st = new StringTokenizer(s, "|"); - value = 0; - while (st.hasMoreTokens()) { - int val = flags.getValue(st.nextToken()); - if (val < 0) { - return -1; - } - value |= val; - } - return value; - } -} - -/* flags */ -/** This key cannot be used for confidentiality (encryption) */ -public static final int FLAG_NOCONF = Flags.NOCONF; - -/** This key cannot be used for authentication */ -public static final int FLAG_NOAUTH = Flags.NOAUTH; - -/** This key cannot be used for authentication or confidentiality */ -public static final int FLAG_NOKEY = Flags.NOKEY; - -/** A zone key */ -public static final int OWNER_ZONE = Flags.ZONE; - -/** A host/end entity key */ -public static final int OWNER_HOST = Flags.HOST; - -/** A user key */ -public static final int OWNER_USER = Flags.USER; - -/* protocols */ -/** Key was created for use with transaction level security */ -public static final int PROTOCOL_TLS = Protocol.TLS; - -/** Key was created for use with email */ -public static final int PROTOCOL_EMAIL = Protocol.EMAIL; - -/** Key was created for use with DNSSEC */ -public static final int PROTOCOL_DNSSEC = Protocol.DNSSEC; - -/** Key was created for use with IPSEC */ -public static final int PROTOCOL_IPSEC = Protocol.IPSEC; - -/** Key was created for use with any protocol */ -public static final int PROTOCOL_ANY = Protocol.ANY; - -KEYRecord() {} - -Record -getObject() { - return new KEYRecord(); -} - -/** - * Creates a KEY Record from the given data - * @param flags Flags describing the key's properties - * @param proto The protocol that the key was created for - * @param alg The key's algorithm - * @param key Binary data representing the key - */ -public -KEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg, - byte [] key) -{ - super(name, Type.KEY, dclass, ttl, flags, proto, alg, key); -} - -/** - * Creates a KEY Record from the given data - * @param flags Flags describing the key's properties - * @param proto The protocol that the key was created for - * @param alg The key's algorithm - * @param key The key as a PublicKey - * @throws DNSSEC.DNSSECException The PublicKey could not be converted into DNS - * format. - */ -public -KEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg, - PublicKey key) throws DNSSEC.DNSSECException -{ - super(name, Type.KEY, dclass, ttl, flags, proto, alg, - DNSSEC.fromPublicKey(key, alg)); - publicKey = key; -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - String flagString = st.getIdentifier(); - flags = Flags.value(flagString); - if (flags < 0) - throw st.exception("Invalid flags: " + flagString); - String protoString = st.getIdentifier(); - proto = Protocol.value(protoString); - if (proto < 0) - throw st.exception("Invalid protocol: " + protoString); - String algString = st.getIdentifier(); - alg = DNSSEC.Algorithm.value(algString); - if (alg < 0) - throw st.exception("Invalid algorithm: " + algString); - /* If this is a null KEY, there's no key data */ - if ((flags & Flags.USE_MASK) == Flags.NOKEY) - key = null; - else - key = st.getBase64(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/KXRecord.java b/src/main/java/core/org/xbill/DNS/KXRecord.java deleted file mode 100644 index 481d21b8..00000000 --- a/src/main/java/core/org/xbill/DNS/KXRecord.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Key Exchange - delegation of authority - * - * @author Brian Wellington - */ - -public class KXRecord extends U16NameBase { - -private static final long serialVersionUID = 7448568832769757809L; - -KXRecord() {} - -Record -getObject() { - return new KXRecord(); -} - -/** - * Creates a KX Record from the given data - * @param preference The preference of this KX. Records with lower priority - * are preferred. - * @param target The host that authority is delegated to - */ -public -KXRecord(Name name, int dclass, long ttl, int preference, Name target) { - super(name, Type.KX, dclass, ttl, preference, "preference", - target, "target"); -} - -/** Returns the target of the KX record */ -public Name -getTarget() { - return getNameField(); -} - -/** Returns the preference of this KX record */ -public int -getPreference() { - return getU16Field(); -} - -public Name -getAdditionalName() { - return getNameField(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/LOCRecord.java b/src/main/java/core/org/xbill/DNS/LOCRecord.java deleted file mode 100644 index 4eddc157..00000000 --- a/src/main/java/core/org/xbill/DNS/LOCRecord.java +++ /dev/null @@ -1,314 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.text.*; - -/** - * Location - describes the physical location of hosts, networks, subnets. - * - * @author Brian Wellington - */ - -public class LOCRecord extends Record { - -private static final long serialVersionUID = 9058224788126750409L; - -private static NumberFormat w2, w3; - -private long size, hPrecision, vPrecision; -private long latitude, longitude, altitude; - -static { - w2 = new DecimalFormat(); - w2.setMinimumIntegerDigits(2); - - w3 = new DecimalFormat(); - w3.setMinimumIntegerDigits(3); -} - -LOCRecord() {} - -Record -getObject() { - return new LOCRecord(); -} - -/** - * Creates an LOC Record from the given data - * @param latitude The latitude of the center of the sphere - * @param longitude The longitude of the center of the sphere - * @param altitude The altitude of the center of the sphere, in m - * @param size The diameter of a sphere enclosing the described entity, in m. - * @param hPrecision The horizontal precision of the data, in m. - * @param vPrecision The vertical precision of the data, in m. -*/ -public -LOCRecord(Name name, int dclass, long ttl, double latitude, double longitude, - double altitude, double size, double hPrecision, double vPrecision) -{ - super(name, Type.LOC, dclass, ttl); - this.latitude = (long)(latitude * 3600 * 1000 + (1L << 31)); - this.longitude = (long)(longitude * 3600 * 1000 + (1L << 31)); - this.altitude = (long)((altitude + 100000) * 100); - this.size = (long)(size * 100); - this.hPrecision = (long)(hPrecision * 100); - this.vPrecision = (long)(vPrecision * 100); -} - -void -rrFromWire(DNSInput in) throws IOException { - int version; - - version = in.readU8(); - if (version != 0) - throw new WireParseException("Invalid LOC version"); - - size = parseLOCformat(in.readU8()); - hPrecision = parseLOCformat(in.readU8()); - vPrecision = parseLOCformat(in.readU8()); - latitude = in.readU32(); - longitude = in.readU32(); - altitude = in.readU32(); -} - -private double -parseFixedPoint(String s) -{ - if (s.matches("^-?\\d+$")) - return Integer.parseInt(s); - else if (s.matches("^-?\\d+\\.\\d*$")) { - String [] parts = s.split("\\."); - double value = Integer.parseInt(parts[0]); - double fraction = Integer.parseInt(parts[1]); - if (value < 0) - fraction *= -1; - int digits = parts[1].length(); - return value + (fraction / Math.pow(10, digits)); - } else - throw new NumberFormatException(); -} - -private long -parsePosition(Tokenizer st, String type) throws IOException { - boolean isLatitude = type.equals("latitude"); - int deg = 0, min = 0; - double sec = 0; - long value; - String s; - - deg = st.getUInt16(); - if (deg > 180 || (deg > 90 && isLatitude)) - throw st.exception("Invalid LOC " + type + " degrees"); - - s = st.getString(); - try { - min = Integer.parseInt(s); - if (min < 0 || min > 59) - throw st.exception("Invalid LOC " + type + " minutes"); - s = st.getString(); - sec = parseFixedPoint(s); - if (sec < 0 || sec >= 60) - throw st.exception("Invalid LOC " + type + " seconds"); - s = st.getString(); - } catch (NumberFormatException e) { - } - - if (s.length() != 1) - throw st.exception("Invalid LOC " + type); - - value = (long) (1000 * (sec + 60L * (min + 60L * deg))); - - char c = Character.toUpperCase(s.charAt(0)); - if ((isLatitude && c == 'S') || (!isLatitude && c == 'W')) - value = -value; - else if ((isLatitude && c != 'N') || (!isLatitude && c != 'E')) - throw st.exception("Invalid LOC " + type); - - value += (1L << 31); - - return value; -} - -private long -parseDouble(Tokenizer st, String type, boolean required, long min, long max, - long defaultValue) -throws IOException -{ - Tokenizer.Token token = st.get(); - if (token.isEOL()) { - if (required) - throw st.exception("Invalid LOC " + type); - st.unget(); - return defaultValue; - } - String s = token.value; - if (s.length() > 1 && s.charAt(s.length() - 1) == 'm') - s = s.substring(0, s.length() - 1); - try { - long value = (long)(100 * parseFixedPoint(s)); - if (value < min || value > max) - throw st.exception("Invalid LOC " + type); - return value; - } - catch (NumberFormatException e) { - throw st.exception("Invalid LOC " + type); - } -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - latitude = parsePosition(st, "latitude"); - longitude = parsePosition(st, "longitude"); - altitude = parseDouble(st, "altitude", true, - -10000000, 4284967295L, 0) + 10000000; - size = parseDouble(st, "size", false, 0, 9000000000L, 100); - hPrecision = parseDouble(st, "horizontal precision", false, - 0, 9000000000L, 1000000); - vPrecision = parseDouble(st, "vertical precision", false, - 0, 9000000000L, 1000); -} - -private void -renderFixedPoint(StringBuffer sb, NumberFormat formatter, long value, - long divisor) -{ - sb.append(value / divisor); - value %= divisor; - if (value != 0) { - sb.append("."); - sb.append(formatter.format(value)); - } -} - -private String -positionToString(long value, char pos, char neg) { - StringBuffer sb = new StringBuffer(); - char direction; - - long temp = value - (1L << 31); - if (temp < 0) { - temp = -temp; - direction = neg; - } else - direction = pos; - - sb.append(temp / (3600 * 1000)); /* degrees */ - temp = temp % (3600 * 1000); - sb.append(" "); - - sb.append(temp / (60 * 1000)); /* minutes */ - temp = temp % (60 * 1000); - sb.append(" "); - - renderFixedPoint(sb, w3, temp, 1000); /* seconds */ - sb.append(" "); - - sb.append(direction); - - return sb.toString(); -} - - -/** Convert to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - - /* Latitude */ - sb.append(positionToString(latitude, 'N', 'S')); - sb.append(" "); - - /* Latitude */ - sb.append(positionToString(longitude, 'E', 'W')); - sb.append(" "); - - /* Altitude */ - renderFixedPoint(sb, w2, altitude - 10000000, 100); - sb.append("m "); - - /* Size */ - renderFixedPoint(sb, w2, size, 100); - sb.append("m "); - - /* Horizontal precision */ - renderFixedPoint(sb, w2, hPrecision, 100); - sb.append("m "); - - /* Vertical precision */ - renderFixedPoint(sb, w2, vPrecision, 100); - sb.append("m"); - - return sb.toString(); -} - -/** Returns the latitude */ -public double -getLatitude() { - return ((double)(latitude - (1L << 31))) / (3600 * 1000); -} - -/** Returns the longitude */ -public double -getLongitude() { - return ((double)(longitude - (1L << 31))) / (3600 * 1000); -} - -/** Returns the altitude */ -public double -getAltitude() { - return ((double)(altitude - 10000000)) / 100; -} - -/** Returns the diameter of the enclosing sphere */ -public double -getSize() { - return ((double)size) / 100; -} - -/** Returns the horizontal precision */ -public double -getHPrecision() { - return ((double)hPrecision) / 100; -} - -/** Returns the horizontal precision */ -public double -getVPrecision() { - return ((double)vPrecision) / 100; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU8(0); /* version */ - out.writeU8(toLOCformat(size)); - out.writeU8(toLOCformat(hPrecision)); - out.writeU8(toLOCformat(vPrecision)); - out.writeU32(latitude); - out.writeU32(longitude); - out.writeU32(altitude); -} - -private static long -parseLOCformat(int b) throws WireParseException { - long out = b >> 4; - int exp = b & 0xF; - if (out > 9 || exp > 9) - throw new WireParseException("Invalid LOC Encoding"); - while (exp-- > 0) - out *= 10; - return (out); -} - -private int -toLOCformat(long l) { - byte exp = 0; - while (l > 9) { - exp++; - l /= 10; - } - return (int)((l << 4) + exp); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Lookup.java b/src/main/java/core/org/xbill/DNS/Lookup.java deleted file mode 100644 index b661f1bc..00000000 --- a/src/main/java/core/org/xbill/DNS/Lookup.java +++ /dev/null @@ -1,657 +0,0 @@ -// Copyright (c) 2002-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.*; -import java.io.*; -import java.net.*; - -/** - * The Lookup object issues queries to caching DNS servers. The input consists - * of a name, an optional type, and an optional class. Caching is enabled - * by default and used when possible to reduce the number of DNS requests. - * A Resolver, which defaults to an ExtendedResolver initialized with the - * resolvers located by the ResolverConfig class, performs the queries. A - * search path of domain suffixes is used to resolve relative names, and is - * also determined by the ResolverConfig class. - * - * A Lookup object may be reused, but should not be used by multiple threads. - * - * @see Cache - * @see Resolver - * @see ResolverConfig - * - * @author Brian Wellington - */ - -public final class Lookup { - -private static Resolver defaultResolver; -private static Name [] defaultSearchPath; -private static Map defaultCaches; -private static int defaultNdots; - -private Resolver resolver; -private Name [] searchPath; -private Cache cache; -private boolean temporary_cache; -private int credibility; -private Name name; -private int type; -private int dclass; -private boolean verbose; -private int iterations; -private boolean foundAlias; -private boolean done; -private boolean doneCurrent; -private List aliases; -private Record [] answers; -private int result; -private String error; -private boolean nxdomain; -private boolean badresponse; -private String badresponse_error; -private boolean networkerror; -private boolean timedout; -private boolean nametoolong; -private boolean referral; - -private static final Name [] noAliases = new Name[0]; - -/** The lookup was successful. */ -public static final int SUCCESSFUL = 0; - -/** - * The lookup failed due to a data or server error. Repeating the lookup - * would not be helpful. - */ -public static final int UNRECOVERABLE = 1; - -/** - * The lookup failed due to a network error. Repeating the lookup may be - * helpful. - */ -public static final int TRY_AGAIN = 2; - -/** The host does not exist. */ -public static final int HOST_NOT_FOUND = 3; - -/** The host exists, but has no records associated with the queried type. */ -public static final int TYPE_NOT_FOUND = 4; - -public static synchronized void -refreshDefault() { - - try { - defaultResolver = new ExtendedResolver(); - } - catch (UnknownHostException e) { - throw new RuntimeException("Failed to initialize resolver"); - } - defaultSearchPath = ResolverConfig.getCurrentConfig().searchPath(); - defaultCaches = new HashMap(); - defaultNdots = ResolverConfig.getCurrentConfig().ndots(); -} - -static { - refreshDefault(); -} - -/** - * Gets the Resolver that will be used as the default by future Lookups. - * @return The default resolver. - */ -public static synchronized Resolver -getDefaultResolver() { - return defaultResolver; -} - -/** - * Sets the default Resolver to be used as the default by future Lookups. - * @param resolver The default resolver. - */ -public static synchronized void -setDefaultResolver(Resolver resolver) { - defaultResolver = resolver; -} - -/** - * Gets the Cache that will be used as the default for the specified - * class by future Lookups. - * @param dclass The class whose cache is being retrieved. - * @return The default cache for the specified class. - */ -public static synchronized Cache -getDefaultCache(int dclass) { - DClass.check(dclass); - Cache c = (Cache) defaultCaches.get(Mnemonic.toInteger(dclass)); - if (c == null) { - c = new Cache(dclass); - defaultCaches.put(Mnemonic.toInteger(dclass), c); - } - return c; -} - -/** - * Sets the Cache to be used as the default for the specified class by future - * Lookups. - * @param cache The default cache for the specified class. - * @param dclass The class whose cache is being set. - */ -public static synchronized void -setDefaultCache(Cache cache, int dclass) { - DClass.check(dclass); - defaultCaches.put(Mnemonic.toInteger(dclass), cache); -} - -/** - * Gets the search path that will be used as the default by future Lookups. - * @return The default search path. - */ -public static synchronized Name [] -getDefaultSearchPath() { - return defaultSearchPath; -} - -/** - * Sets the search path to be used as the default by future Lookups. - * @param domains The default search path. - */ -public static synchronized void -setDefaultSearchPath(Name [] domains) { - defaultSearchPath = domains; -} - -/** - * Sets the search path that will be used as the default by future Lookups. - * @param domains The default search path. - * @throws TextParseException A name in the array is not a valid DNS name. - */ -public static synchronized void -setDefaultSearchPath(String [] domains) throws TextParseException { - if (domains == null) { - defaultSearchPath = null; - return; - } - Name [] newdomains = new Name[domains.length]; - for (int i = 0; i < domains.length; i++) - newdomains[i] = Name.fromString(domains[i], Name.root); - defaultSearchPath = newdomains; -} - -/** - * Sets a custom logger that will be used to log the send and received packets. - * @param logger - */ -public static synchronized void -setPacketLogger(PacketLogger logger) -{ - Client.setPacketLogger(logger); -} - -private final void -reset() { - iterations = 0; - foundAlias = false; - done = false; - doneCurrent = false; - aliases = null; - answers = null; - result = -1; - error = null; - nxdomain = false; - badresponse = false; - badresponse_error = null; - networkerror = false; - timedout = false; - nametoolong = false; - referral = false; - if (temporary_cache) - cache.clearCache(); -} - -/** - * Create a Lookup object that will find records of the given name, type, - * and class. The lookup will use the default cache, resolver, and search - * path, and look for records that are reasonably credible. - * @param name The name of the desired records - * @param type The type of the desired records - * @param dclass The class of the desired records - * @throws IllegalArgumentException The type is a meta type other than ANY. - * @see Cache - * @see Resolver - * @see Credibility - * @see Name - * @see Type - * @see DClass - */ -public -Lookup(Name name, int type, int dclass) { - Type.check(type); - DClass.check(dclass); - if (!Type.isRR(type) && type != Type.ANY) - throw new IllegalArgumentException("Cannot query for " + - "meta-types other than ANY"); - this.name = name; - this.type = type; - this.dclass = dclass; - synchronized (Lookup.class) { - this.resolver = getDefaultResolver(); - this.searchPath = getDefaultSearchPath(); - this.cache = getDefaultCache(dclass); - } - this.credibility = Credibility.NORMAL; - this.verbose = Options.check("verbose"); - this.result = -1; -} - -/** - * Create a Lookup object that will find records of the given name and type - * in the IN class. - * @param name The name of the desired records - * @param type The type of the desired records - * @throws IllegalArgumentException The type is a meta type other than ANY. - * @see #Lookup(Name,int,int) - */ -public -Lookup(Name name, int type) { - this(name, type, DClass.IN); -} - -/** - * Create a Lookup object that will find records of type A at the given name - * in the IN class. - * @param name The name of the desired records - * @see #Lookup(Name,int,int) - */ -public -Lookup(Name name) { - this(name, Type.A, DClass.IN); -} - -/** - * Create a Lookup object that will find records of the given name, type, - * and class. - * @param name The name of the desired records - * @param type The type of the desired records - * @param dclass The class of the desired records - * @throws TextParseException The name is not a valid DNS name - * @throws IllegalArgumentException The type is a meta type other than ANY. - * @see #Lookup(Name,int,int) - */ -public -Lookup(String name, int type, int dclass) throws TextParseException { - this(Name.fromString(name), type, dclass); -} - -/** - * Create a Lookup object that will find records of the given name and type - * in the IN class. - * @param name The name of the desired records - * @param type The type of the desired records - * @throws TextParseException The name is not a valid DNS name - * @throws IllegalArgumentException The type is a meta type other than ANY. - * @see #Lookup(Name,int,int) - */ -public -Lookup(String name, int type) throws TextParseException { - this(Name.fromString(name), type, DClass.IN); -} - -/** - * Create a Lookup object that will find records of type A at the given name - * in the IN class. - * @param name The name of the desired records - * @throws TextParseException The name is not a valid DNS name - * @see #Lookup(Name,int,int) - */ -public -Lookup(String name) throws TextParseException { - this(Name.fromString(name), Type.A, DClass.IN); -} - -/** - * Sets the resolver to use when performing this lookup. This overrides the - * default value. - * @param resolver The resolver to use. - */ -public void -setResolver(Resolver resolver) { - this.resolver = resolver; -} - -/** - * Sets the search path to use when performing this lookup. This overrides the - * default value. - * @param domains An array of names containing the search path. - */ -public void -setSearchPath(Name [] domains) { - this.searchPath = domains; -} - -/** - * Sets the search path to use when performing this lookup. This overrides the - * default value. - * @param domains An array of names containing the search path. - * @throws TextParseException A name in the array is not a valid DNS name. - */ -public void -setSearchPath(String [] domains) throws TextParseException { - if (domains == null) { - this.searchPath = null; - return; - } - Name [] newdomains = new Name[domains.length]; - for (int i = 0; i < domains.length; i++) - newdomains[i] = Name.fromString(domains[i], Name.root); - this.searchPath = newdomains; -} - -/** - * Sets the cache to use when performing this lookup. This overrides the - * default value. If the results of this lookup should not be permanently - * cached, null can be provided here. - * @param cache The cache to use. - */ -public void -setCache(Cache cache) { - if (cache == null) { - this.cache = new Cache(dclass); - this.temporary_cache = true; - } else { - this.cache = cache; - this.temporary_cache = false; - } -} - -/** - * Sets ndots to use when performing this lookup, overriding the default value. - * Specifically, this refers to the number of "dots" which, if present in a - * name, indicate that a lookup for the absolute name should be attempted - * before appending any search path elements. - * @param ndots The ndots value to use, which must be greater than or equal to - * 0. - */ -public void -setNdots(int ndots) { - if (ndots < 0) - throw new IllegalArgumentException("Illegal ndots value: " + - ndots); - defaultNdots = ndots; -} - -/** - * Sets the minimum credibility level that will be accepted when performing - * the lookup. This defaults to Credibility.NORMAL. - * @param credibility The minimum credibility level. - */ -public void -setCredibility(int credibility) { - this.credibility = credibility; -} - -private void -follow(Name name, Name oldname) { - foundAlias = true; - badresponse = false; - networkerror = false; - timedout = false; - nxdomain = false; - referral = false; - iterations++; - if (iterations >= 10 || name.equals(oldname)) { - result = UNRECOVERABLE; - error = "CNAME loop"; - done = true; - return; - } - if (aliases == null) - aliases = new ArrayList(); - aliases.add(oldname); - lookup(name); -} - -private void -processResponse(Name name, SetResponse response) { - if (response.isSuccessful()) { - RRset [] rrsets = response.answers(); - List l = new ArrayList(); - Iterator it; - int i; - - for (i = 0; i < rrsets.length; i++) { - it = rrsets[i].rrs(); - while (it.hasNext()) - l.add(it.next()); - } - - result = SUCCESSFUL; - answers = (Record []) l.toArray(new Record[l.size()]); - done = true; - } else if (response.isNXDOMAIN()) { - nxdomain = true; - doneCurrent = true; - if (iterations > 0) { - result = HOST_NOT_FOUND; - done = true; - } - } else if (response.isNXRRSET()) { - result = TYPE_NOT_FOUND; - answers = null; - done = true; - } else if (response.isCNAME()) { - CNAMERecord cname = response.getCNAME(); - follow(cname.getTarget(), name); - } else if (response.isDNAME()) { - DNAMERecord dname = response.getDNAME(); - try { - follow(name.fromDNAME(dname), name); - } catch (NameTooLongException e) { - result = UNRECOVERABLE; - error = "Invalid DNAME target"; - done = true; - } - } else if (response.isDelegation()) { - // We shouldn't get a referral. Ignore it. - referral = true; - } -} - -private void -lookup(Name current) { - SetResponse sr = cache.lookupRecords(current, type, credibility); - if (verbose) { - System.err.println("lookup " + current + " " + - Type.string(type)); - System.err.println(sr); - } - processResponse(current, sr); - if (done || doneCurrent) - return; - - Record question = Record.newRecord(current, type, dclass); - Message query = Message.newQuery(question); - Message response = null; - try { - response = resolver.send(query); - } - catch (IOException e) { - // A network error occurred. Press on. - if (e instanceof InterruptedIOException) - timedout = true; - else - networkerror = true; - return; - } - int rcode = response.getHeader().getRcode(); - if (rcode != Rcode.NOERROR && rcode != Rcode.NXDOMAIN) { - // The server we contacted is broken or otherwise unhelpful. - // Press on. - badresponse = true; - badresponse_error = Rcode.string(rcode); - return; - } - - if (!query.getQuestion().equals(response.getQuestion())) { - // The answer doesn't match the question. That's not good. - badresponse = true; - badresponse_error = "response does not match query"; - return; - } - - sr = cache.addMessage(response); - if (sr == null) - sr = cache.lookupRecords(current, type, credibility); - if (verbose) { - System.err.println("queried " + current + " " + - Type.string(type)); - System.err.println(sr); - } - processResponse(current, sr); -} - -private void -resolve(Name current, Name suffix) { - doneCurrent = false; - Name tname = null; - if (suffix == null) - tname = current; - else { - try { - tname = Name.concatenate(current, suffix); - } - catch (NameTooLongException e) { - nametoolong = true; - return; - } - } - lookup(tname); -} - -/** - * Performs the lookup, using the specified Cache, Resolver, and search path. - * @return The answers, or null if none are found. - */ -public Record [] -run() { - if (done) - reset(); - if (name.isAbsolute()) - resolve(name, null); - else if (searchPath == null) - resolve(name, Name.root); - else { - if (name.labels() > defaultNdots) - resolve(name, Name.root); - if (done) - return answers; - - for (int i = 0; i < searchPath.length; i++) { - resolve(name, searchPath[i]); - if (done) - return answers; - else if (foundAlias) - break; - } - } - if (!done) { - if (badresponse) { - result = TRY_AGAIN; - error = badresponse_error; - done = true; - } else if (timedout) { - result = TRY_AGAIN; - error = "timed out"; - done = true; - } else if (networkerror) { - result = TRY_AGAIN; - error = "network error"; - done = true; - } else if (nxdomain) { - result = HOST_NOT_FOUND; - done = true; - } else if (referral) { - result = UNRECOVERABLE; - error = "referral"; - done = true; - } else if (nametoolong) { - result = UNRECOVERABLE; - error = "name too long"; - done = true; - } - } - return answers; -} - -private void -checkDone() { - if (done && result != -1) - return; - StringBuffer sb = new StringBuffer("Lookup of " + name + " "); - if (dclass != DClass.IN) - sb.append(DClass.string(dclass) + " "); - sb.append(Type.string(type) + " isn't done"); - throw new IllegalStateException(sb.toString()); -} - -/** - * Returns the answers from the lookup. - * @return The answers, or null if none are found. - * @throws IllegalStateException The lookup has not completed. - */ -public Record [] -getAnswers() { - checkDone(); - return answers; -} - -/** - * Returns all known aliases for this name. Whenever a CNAME/DNAME is - * followed, an alias is added to this array. The last element in this - * array will be the owner name for records in the answer, if there are any. - * @return The aliases. - * @throws IllegalStateException The lookup has not completed. - */ -public Name [] -getAliases() { - checkDone(); - if (aliases == null) - return noAliases; - return (Name []) aliases.toArray(new Name[aliases.size()]); -} - -/** - * Returns the result code of the lookup. - * @return The result code, which can be SUCCESSFUL, UNRECOVERABLE, TRY_AGAIN, - * HOST_NOT_FOUND, or TYPE_NOT_FOUND. - * @throws IllegalStateException The lookup has not completed. - */ -public int -getResult() { - checkDone(); - return result; -} - -/** - * Returns an error string describing the result code of this lookup. - * @return A string, which may either directly correspond the result code - * or be more specific. - * @throws IllegalStateException The lookup has not completed. - */ -public String -getErrorString() { - checkDone(); - if (error != null) - return error; - switch (result) { - case SUCCESSFUL: return "successful"; - case UNRECOVERABLE: return "unrecoverable error"; - case TRY_AGAIN: return "try again"; - case HOST_NOT_FOUND: return "host not found"; - case TYPE_NOT_FOUND: return "type not found"; - } - throw new IllegalStateException("unknown result"); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/MBRecord.java b/src/main/java/core/org/xbill/DNS/MBRecord.java deleted file mode 100644 index 6b65edf4..00000000 --- a/src/main/java/core/org/xbill/DNS/MBRecord.java +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Mailbox Record - specifies a host containing a mailbox. - * - * @author Brian Wellington - */ - -public class MBRecord extends SingleNameBase { - -private static final long serialVersionUID = 532349543479150419L; - -MBRecord() {} - -Record -getObject() { - return new MBRecord(); -} - -/** - * Creates a new MB Record with the given data - * @param mailbox The host containing the mailbox for the domain. - */ -public -MBRecord(Name name, int dclass, long ttl, Name mailbox) { - super(name, Type.MB, dclass, ttl, mailbox, "mailbox"); -} - -/** Gets the mailbox for the domain */ -public Name -getMailbox() { - return getSingleName(); -} - -public Name -getAdditionalName() { - return getSingleName(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/MDRecord.java b/src/main/java/core/org/xbill/DNS/MDRecord.java deleted file mode 100644 index dbf51af9..00000000 --- a/src/main/java/core/org/xbill/DNS/MDRecord.java +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Mail Destination Record - specifies a mail agent which delivers mail - * for a domain (obsolete) - * - * @author Brian Wellington - */ - -public class MDRecord extends SingleNameBase { - -private static final long serialVersionUID = 5268878603762942202L; - -MDRecord() {} - -Record -getObject() { - return new MDRecord(); -} - -/** - * Creates a new MD Record with the given data - * @param mailAgent The mail agent that delivers mail for the domain. - */ -public -MDRecord(Name name, int dclass, long ttl, Name mailAgent) { - super(name, Type.MD, dclass, ttl, mailAgent, "mail agent"); -} - -/** Gets the mail agent for the domain */ -public Name -getMailAgent() { - return getSingleName(); -} - -public Name -getAdditionalName() { - return getSingleName(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/MFRecord.java b/src/main/java/core/org/xbill/DNS/MFRecord.java deleted file mode 100644 index ff293d7e..00000000 --- a/src/main/java/core/org/xbill/DNS/MFRecord.java +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Mail Forwarder Record - specifies a mail agent which forwards mail - * for a domain (obsolete) - * - * @author Brian Wellington - */ - -public class MFRecord extends SingleNameBase { - -private static final long serialVersionUID = -6670449036843028169L; - -MFRecord() {} - -Record -getObject() { - return new MFRecord(); -} - -/** - * Creates a new MF Record with the given data - * @param mailAgent The mail agent that forwards mail for the domain. - */ -public -MFRecord(Name name, int dclass, long ttl, Name mailAgent) { - super(name, Type.MF, dclass, ttl, mailAgent, "mail agent"); -} - -/** Gets the mail agent for the domain */ -public Name -getMailAgent() { - return getSingleName(); -} - -public Name -getAdditionalName() { - return getSingleName(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/MGRecord.java b/src/main/java/core/org/xbill/DNS/MGRecord.java deleted file mode 100644 index 5752f498..00000000 --- a/src/main/java/core/org/xbill/DNS/MGRecord.java +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Mail Group Record - specifies a mailbox which is a member of a mail group. - * - * @author Brian Wellington - */ - -public class MGRecord extends SingleNameBase { - -private static final long serialVersionUID = -3980055550863644582L; - -MGRecord() {} - -Record -getObject() { - return new MGRecord(); -} - -/** - * Creates a new MG Record with the given data - * @param mailbox The mailbox that is a member of the group specified by the - * domain. - */ -public -MGRecord(Name name, int dclass, long ttl, Name mailbox) { - super(name, Type.MG, dclass, ttl, mailbox, "mailbox"); -} - -/** Gets the mailbox in the mail group specified by the domain */ -public Name -getMailbox() { - return getSingleName(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/MINFORecord.java b/src/main/java/core/org/xbill/DNS/MINFORecord.java deleted file mode 100644 index 4324cdab..00000000 --- a/src/main/java/core/org/xbill/DNS/MINFORecord.java +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * Mailbox information Record - lists the address responsible for a mailing - * list/mailbox and the address to receive error messages relating to the - * mailing list/mailbox. - * - * @author Brian Wellington - */ - -public class MINFORecord extends Record { - -private static final long serialVersionUID = -3962147172340353796L; - -private Name responsibleAddress; -private Name errorAddress; - -MINFORecord() {} - -Record -getObject() { - return new MINFORecord(); -} - -/** - * Creates an MINFO Record from the given data - * @param responsibleAddress The address responsible for the - * mailing list/mailbox. - * @param errorAddress The address to receive error messages relating to the - * mailing list/mailbox. - */ -public -MINFORecord(Name name, int dclass, long ttl, - Name responsibleAddress, Name errorAddress) -{ - super(name, Type.MINFO, dclass, ttl); - - this.responsibleAddress = checkName("responsibleAddress", - responsibleAddress); - this.errorAddress = checkName("errorAddress", errorAddress); -} - -void -rrFromWire(DNSInput in) throws IOException { - responsibleAddress = new Name(in); - errorAddress = new Name(in); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - responsibleAddress = st.getName(origin); - errorAddress = st.getName(origin); -} - -/** Converts the MINFO Record to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(responsibleAddress); - sb.append(" "); - sb.append(errorAddress); - return sb.toString(); -} - -/** Gets the address responsible for the mailing list/mailbox. */ -public Name -getResponsibleAddress() { - return responsibleAddress; -} - -/** - * Gets the address to receive error messages relating to the mailing - * list/mailbox. - */ -public Name -getErrorAddress() { - return errorAddress; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - responsibleAddress.toWire(out, null, canonical); - errorAddress.toWire(out, null, canonical); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/MRRecord.java b/src/main/java/core/org/xbill/DNS/MRRecord.java deleted file mode 100644 index a7ff4fc9..00000000 --- a/src/main/java/core/org/xbill/DNS/MRRecord.java +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Mailbox Rename Record - specifies a rename of a mailbox. - * - * @author Brian Wellington - */ - -public class MRRecord extends SingleNameBase { - -private static final long serialVersionUID = -5617939094209927533L; - -MRRecord() {} - -Record -getObject() { - return new MRRecord(); -} - -/** - * Creates a new MR Record with the given data - * @param newName The new name of the mailbox specified by the domain. - * domain. - */ -public -MRRecord(Name name, int dclass, long ttl, Name newName) { - super(name, Type.MR, dclass, ttl, newName, "new name"); -} - -/** Gets the new name of the mailbox specified by the domain */ -public Name -getNewName() { - return getSingleName(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/MXRecord.java b/src/main/java/core/org/xbill/DNS/MXRecord.java deleted file mode 100644 index 111977d1..00000000 --- a/src/main/java/core/org/xbill/DNS/MXRecord.java +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Mail Exchange - specifies where mail to a domain is sent - * - * @author Brian Wellington - */ - -public class MXRecord extends U16NameBase { - -private static final long serialVersionUID = 2914841027584208546L; - -MXRecord() {} - -Record -getObject() { - return new MXRecord(); -} - -/** - * Creates an MX Record from the given data - * @param priority The priority of this MX. Records with lower priority - * are preferred. - * @param target The host that mail is sent to - */ -public -MXRecord(Name name, int dclass, long ttl, int priority, Name target) { - super(name, Type.MX, dclass, ttl, priority, "priority", - target, "target"); -} - -/** Returns the target of the MX record */ -public Name -getTarget() { - return getNameField(); -} - -/** Returns the priority of this MX record */ -public int -getPriority() { - return getU16Field(); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(u16Field); - nameField.toWire(out, c, canonical); -} - -public Name -getAdditionalName() { - return getNameField(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Master.java b/src/main/java/core/org/xbill/DNS/Master.java deleted file mode 100644 index 30d3834a..00000000 --- a/src/main/java/core/org/xbill/DNS/Master.java +++ /dev/null @@ -1,428 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; - -/** - * A DNS master file parser. This incrementally parses the file, returning - * one record at a time. When directives are seen, they are added to the - * state and used when parsing future records. - * - * @author Brian Wellington - */ - -public class Master { - -private Name origin; -private File file; -private Record last = null; -private long defaultTTL; -private Master included = null; -private Tokenizer st; -private int currentType; -private int currentDClass; -private long currentTTL; -private boolean needSOATTL; - -private Generator generator; -private List generators; -private boolean noExpandGenerate; - -Master(File file, Name origin, long initialTTL) throws IOException { - if (origin != null && !origin.isAbsolute()) { - throw new RelativeNameException(origin); - } - this.file = file; - st = new Tokenizer(file); - this.origin = origin; - defaultTTL = initialTTL; -} - -/** - * Initializes the master file reader and opens the specified master file. - * @param filename The master file. - * @param origin The initial origin to append to relative names. - * @param ttl The initial default TTL. - * @throws IOException The master file could not be opened. - */ -public -Master(String filename, Name origin, long ttl) throws IOException { - this(new File(filename), origin, ttl); -} - -/** - * Initializes the master file reader and opens the specified master file. - * @param filename The master file. - * @param origin The initial origin to append to relative names. - * @throws IOException The master file could not be opened. - */ -public -Master(String filename, Name origin) throws IOException { - this(new File(filename), origin, -1); -} - -/** - * Initializes the master file reader and opens the specified master file. - * @param filename The master file. - * @throws IOException The master file could not be opened. - */ -public -Master(String filename) throws IOException { - this(new File(filename), null, -1); -} - -/** - * Initializes the master file reader. - * @param in The input stream containing a master file. - * @param origin The initial origin to append to relative names. - * @param ttl The initial default TTL. - */ -public -Master(InputStream in, Name origin, long ttl) { - if (origin != null && !origin.isAbsolute()) { - throw new RelativeNameException(origin); - } - st = new Tokenizer(in); - this.origin = origin; - defaultTTL = ttl; -} - -/** - * Initializes the master file reader. - * @param in The input stream containing a master file. - * @param origin The initial origin to append to relative names. - */ -public -Master(InputStream in, Name origin) { - this(in, origin, -1); -} - -/** - * Initializes the master file reader. - * @param in The input stream containing a master file. - */ -public -Master(InputStream in) { - this(in, null, -1); -} - -private Name -parseName(String s, Name origin) throws TextParseException { - try { - return Name.fromString(s, origin); - } - catch (TextParseException e) { - throw st.exception(e.getMessage()); - } -} - -private void -parseTTLClassAndType() throws IOException { - String s; - boolean seen_class = false; - - - // This is a bit messy, since any of the following are legal: - // class ttl type - // ttl class type - // class type - // ttl type - // type - seen_class = false; - s = st.getString(); - if ((currentDClass = DClass.value(s)) >= 0) { - s = st.getString(); - seen_class = true; - } - - currentTTL = -1; - try { - currentTTL = TTL.parseTTL(s); - s = st.getString(); - } - catch (NumberFormatException e) { - if (defaultTTL >= 0) - currentTTL = defaultTTL; - else if (last != null) - currentTTL = last.getTTL(); - } - - if (!seen_class) { - if ((currentDClass = DClass.value(s)) >= 0) { - s = st.getString(); - } else { - currentDClass = DClass.IN; - } - } - - if ((currentType = Type.value(s)) < 0) - throw st.exception("Invalid type '" + s + "'"); - - // BIND allows a missing TTL for the initial SOA record, and uses - // the SOA minimum value. If the SOA is not the first record, - // this is an error. - if (currentTTL < 0) { - if (currentType != Type.SOA) - throw st.exception("missing TTL"); - needSOATTL = true; - currentTTL = 0; - } -} - -private long -parseUInt32(String s) { - if (!Character.isDigit(s.charAt(0))) - return -1; - try { - long l = Long.parseLong(s); - if (l < 0 || l > 0xFFFFFFFFL) - return -1; - return l; - } - catch (NumberFormatException e) { - return -1; - } -} - -private void -startGenerate() throws IOException { - String s; - int n; - - // The first field is of the form start-end[/step] - // Regexes would be useful here. - s = st.getIdentifier(); - n = s.indexOf("-"); - if (n < 0) - throw st.exception("Invalid $GENERATE range specifier: " + s); - String startstr = s.substring(0, n); - String endstr = s.substring(n + 1); - String stepstr = null; - n = endstr.indexOf("/"); - if (n >= 0) { - stepstr = endstr.substring(n + 1); - endstr = endstr.substring(0, n); - } - long start = parseUInt32(startstr); - long end = parseUInt32(endstr); - long step; - if (stepstr != null) - step = parseUInt32(stepstr); - else - step = 1; - if (start < 0 || end < 0 || start > end || step <= 0) - throw st.exception("Invalid $GENERATE range specifier: " + s); - - // The next field is the name specification. - String nameSpec = st.getIdentifier(); - - // Then the ttl/class/type, in the same form as a normal record. - // Only some types are supported. - parseTTLClassAndType(); - if (!Generator.supportedType(currentType)) - throw st.exception("$GENERATE does not support " + - Type.string(currentType) + " records"); - - // Next comes the rdata specification. - String rdataSpec = st.getIdentifier(); - - // That should be the end. However, we don't want to move past the - // line yet, so put back the EOL after reading it. - st.getEOL(); - st.unget(); - - generator = new Generator(start, end, step, nameSpec, - currentType, currentDClass, currentTTL, - rdataSpec, origin); - if (generators == null) - generators = new ArrayList(1); - generators.add(generator); -} - -private void -endGenerate() throws IOException { - // Read the EOL that we put back before. - st.getEOL(); - - generator = null; -} - -private Record -nextGenerated() throws IOException { - try { - return generator.nextRecord(); - } - catch (Tokenizer.TokenizerException e) { - throw st.exception("Parsing $GENERATE: " + e.getBaseMessage()); - } - catch (TextParseException e) { - throw st.exception("Parsing $GENERATE: " + e.getMessage()); - } -} - -/** - * Returns the next record in the master file. This will process any - * directives before the next record. - * @return The next record. - * @throws IOException The master file could not be read, or was syntactically - * invalid. - */ -public Record -_nextRecord() throws IOException { - Tokenizer.Token token; - String s; - - if (included != null) { - Record rec = included.nextRecord(); - if (rec != null) - return rec; - included = null; - } - if (generator != null) { - Record rec = nextGenerated(); - if (rec != null) - return rec; - endGenerate(); - } - while (true) { - Name name; - - token = st.get(true, false); - if (token.type == Tokenizer.WHITESPACE) { - Tokenizer.Token next = st.get(); - if (next.type == Tokenizer.EOL) - continue; - else if (next.type == Tokenizer.EOF) - return null; - else - st.unget(); - if (last == null) - throw st.exception("no owner"); - name = last.getName(); - } - else if (token.type == Tokenizer.EOL) - continue; - else if (token.type == Tokenizer.EOF) - return null; - else if (((String) token.value).charAt(0) == '$') { - s = token.value; - - if (s.equalsIgnoreCase("$ORIGIN")) { - origin = st.getName(Name.root); - st.getEOL(); - continue; - } else if (s.equalsIgnoreCase("$TTL")) { - defaultTTL = st.getTTL(); - st.getEOL(); - continue; - } else if (s.equalsIgnoreCase("$INCLUDE")) { - String filename = st.getString(); - File newfile; - if (file != null) { - String parent = file.getParent(); - newfile = new File(parent, filename); - } else { - newfile = new File(filename); - } - Name incorigin = origin; - token = st.get(); - if (token.isString()) { - incorigin = parseName(token.value, - Name.root); - st.getEOL(); - } - included = new Master(newfile, incorigin, - defaultTTL); - /* - * If we continued, we wouldn't be looking in - * the new file. Recursing works better. - */ - return nextRecord(); - } else if (s.equalsIgnoreCase("$GENERATE")) { - if (generator != null) - throw new IllegalStateException - ("cannot nest $GENERATE"); - startGenerate(); - if (noExpandGenerate) { - endGenerate(); - continue; - } - return nextGenerated(); - } else { - throw st.exception("Invalid directive: " + s); - } - } else { - s = token.value; - name = parseName(s, origin); - if (last != null && name.equals(last.getName())) { - name = last.getName(); - } - } - - parseTTLClassAndType(); - last = Record.fromString(name, currentType, currentDClass, - currentTTL, st, origin); - if (needSOATTL) { - long ttl = ((SOARecord)last).getMinimum(); - last.setTTL(ttl); - defaultTTL = ttl; - needSOATTL = false; - } - return last; - } -} - -/** - * Returns the next record in the master file. This will process any - * directives before the next record. - * @return The next record. - * @throws IOException The master file could not be read, or was syntactically - * invalid. - */ -public Record -nextRecord() throws IOException { - Record rec = null; - try { - rec = _nextRecord(); - } - finally { - if (rec == null) { - st.close(); - } - } - return rec; -} - -/** - * Specifies whether $GENERATE statements should be expanded. Whether - * expanded or not, the specifications for generated records are available - * by calling {@link #generators}. This must be called before a $GENERATE - * statement is seen during iteration to have an effect. - */ -public void -expandGenerate(boolean wantExpand) { - noExpandGenerate = !wantExpand; -} - -/** - * Returns an iterator over the generators specified in the master file; that - * is, the parsed contents of $GENERATE statements. - * @see Generator - */ -public Iterator -generators() { - if (generators != null) - return Collections.unmodifiableList(generators).iterator(); - else - return Collections.EMPTY_LIST.iterator(); -} - -protected void -finalize() { - if (st != null) - st.close(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Message.java b/src/main/java/core/org/xbill/DNS/Message.java deleted file mode 100644 index 8d1d5ae0..00000000 --- a/src/main/java/core/org/xbill/DNS/Message.java +++ /dev/null @@ -1,634 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.*; -import java.io.*; -import java.nio.ByteBuffer; - -/** - * A DNS Message. A message is the basic unit of communication between - * the client and server of a DNS operation. A message consists of a Header - * and 4 message sections. - * @see Resolver - * @see Header - * @see Section - * - * @author Brian Wellington - */ - -public class Message implements Cloneable { - -/** The maximum length of a message in wire format. */ -public static final int MAXLENGTH = 65535; - -private Header header; -private List [] sections; -private int size; -private TSIG tsigkey; -private TSIGRecord querytsig; -private int tsigerror; - -int tsigstart; -int tsigState; -int sig0start; - -/* The message was not signed */ -static final int TSIG_UNSIGNED = 0; - -/* The message was signed and verification succeeded */ -static final int TSIG_VERIFIED = 1; - -/* The message was an unsigned message in multiple-message response */ -static final int TSIG_INTERMEDIATE = 2; - -/* The message was signed and no verification was attempted. */ -static final int TSIG_SIGNED = 3; - -/* - * The message was signed and verification failed, or was not signed - * when it should have been. - */ -static final int TSIG_FAILED = 4; - -private static Record [] emptyRecordArray = new Record[0]; -private static RRset [] emptyRRsetArray = new RRset[0]; - -private -Message(Header header) { - sections = new List[4]; - this.header = header; -} - -/** Creates a new Message with the specified Message ID */ -public -Message(int id) { - this(new Header(id)); -} - -/** Creates a new Message with a random Message ID */ -public -Message() { - this(new Header()); -} - -/** - * Creates a new Message with a random Message ID suitable for sending as a - * query. - * @param r A record containing the question - */ -public static Message -newQuery(Record r) { - Message m = new Message(); - m.header.setOpcode(Opcode.QUERY); - m.header.setFlag(Flags.RD); - m.addRecord(r, Section.QUESTION); - return m; -} - -/** - * Creates a new Message to contain a dynamic update. A random Message ID - * and the zone are filled in. - * @param zone The zone to be updated - */ -public static Message -newUpdate(Name zone) { - return new Update(zone); -} - -Message(DNSInput in) throws IOException { - this(new Header(in)); - boolean isUpdate = (header.getOpcode() == Opcode.UPDATE); - boolean truncated = header.getFlag(Flags.TC); - try { - for (int i = 0; i < 4; i++) { - int count = header.getCount(i); - if (count > 0) - sections[i] = new ArrayList(count); - for (int j = 0; j < count; j++) { - int pos = in.current(); - Record rec = Record.fromWire(in, i, isUpdate); - sections[i].add(rec); - if (i == Section.ADDITIONAL) { - if (rec.getType() == Type.TSIG) - tsigstart = pos; - if (rec.getType() == Type.SIG) { - SIGRecord sig = (SIGRecord) rec; - if (sig.getTypeCovered() == 0) - sig0start = pos; - } - } - } - } - } catch (WireParseException e) { - if (!truncated) - throw e; - } - size = in.current(); -} - -/** - * Creates a new Message from its DNS wire format representation - * @param b A byte array containing the DNS Message. - */ -public -Message(byte [] b) throws IOException { - this(new DNSInput(b)); -} - -/** - * Creates a new Message from its DNS wire format representation - * @param byteBuffer A ByteBuffer containing the DNS Message. - */ -public -Message(ByteBuffer byteBuffer) throws IOException { - this(new DNSInput(byteBuffer)); -} - -/** - * Replaces the Header with a new one. - * @see Header - */ -public void -setHeader(Header h) { - header = h; -} - -/** - * Retrieves the Header. - * @see Header - */ -public Header -getHeader() { - return header; -} - -/** - * Adds a record to a section of the Message, and adjusts the header. - * @see Record - * @see Section - */ -public void -addRecord(Record r, int section) { - if (sections[section] == null) - sections[section] = new LinkedList(); - header.incCount(section); - sections[section].add(r); -} - -/** - * Removes a record from a section of the Message, and adjusts the header. - * @see Record - * @see Section - */ -public boolean -removeRecord(Record r, int section) { - if (sections[section] != null && sections[section].remove(r)) { - header.decCount(section); - return true; - } - else - return false; -} - -/** - * Removes all records from a section of the Message, and adjusts the header. - * @see Record - * @see Section - */ -public void -removeAllRecords(int section) { - sections[section] = null; - header.setCount(section, 0); -} - -/** - * Determines if the given record is already present in the given section. - * @see Record - * @see Section - */ -public boolean -findRecord(Record r, int section) { - return (sections[section] != null && sections[section].contains(r)); -} - -/** - * Determines if the given record is already present in any section. - * @see Record - * @see Section - */ -public boolean -findRecord(Record r) { - for (int i = Section.ANSWER; i <= Section.ADDITIONAL; i++) - if (sections[i] != null && sections[i].contains(r)) - return true; - return false; -} - -/** - * Determines if an RRset with the given name and type is already - * present in the given section. - * @see RRset - * @see Section - */ -public boolean -findRRset(Name name, int type, int section) { - if (sections[section] == null) - return false; - for (int i = 0; i < sections[section].size(); i++) { - Record r = (Record) sections[section].get(i); - if (r.getType() == type && name.equals(r.getName())) - return true; - } - return false; -} - -/** - * Determines if an RRset with the given name and type is already - * present in any section. - * @see RRset - * @see Section - */ -public boolean -findRRset(Name name, int type) { - return (findRRset(name, type, Section.ANSWER) || - findRRset(name, type, Section.AUTHORITY) || - findRRset(name, type, Section.ADDITIONAL)); -} - -/** - * Returns the first record in the QUESTION section. - * @see Record - * @see Section - */ -public Record -getQuestion() { - List l = sections[Section.QUESTION]; - if (l == null || l.size() == 0) - return null; - return (Record) l.get(0); -} - -/** - * Returns the TSIG record from the ADDITIONAL section, if one is present. - * @see TSIGRecord - * @see TSIG - * @see Section - */ -public TSIGRecord -getTSIG() { - int count = header.getCount(Section.ADDITIONAL); - if (count == 0) - return null; - List l = sections[Section.ADDITIONAL]; - Record rec = (Record) l.get(count - 1); - if (rec.type != Type.TSIG) - return null; - return (TSIGRecord) rec; -} - -/** - * Was this message signed by a TSIG? - * @see TSIG - */ -public boolean -isSigned() { - return (tsigState == TSIG_SIGNED || - tsigState == TSIG_VERIFIED || - tsigState == TSIG_FAILED); -} - -/** - * If this message was signed by a TSIG, was the TSIG verified? - * @see TSIG - */ -public boolean -isVerified() { - return (tsigState == TSIG_VERIFIED); -} - -/** - * Returns the OPT record from the ADDITIONAL section, if one is present. - * @see OPTRecord - * @see Section - */ -public OPTRecord -getOPT() { - Record [] additional = getSectionArray(Section.ADDITIONAL); - for (int i = 0; i < additional.length; i++) - if (additional[i] instanceof OPTRecord) - return (OPTRecord) additional[i]; - return null; -} - -/** - * Returns the message's rcode (error code). This incorporates the EDNS - * extended rcode. - */ -public int -getRcode() { - int rcode = header.getRcode(); - OPTRecord opt = getOPT(); - if (opt != null) - rcode += (opt.getExtendedRcode() << 4); - return rcode; -} - -/** - * Returns an array containing all records in the given section, or an - * empty array if the section is empty. - * @see Record - * @see Section - */ -public Record [] -getSectionArray(int section) { - if (sections[section] == null) - return emptyRecordArray; - List l = sections[section]; - return (Record []) l.toArray(new Record[l.size()]); -} - -private static boolean -sameSet(Record r1, Record r2) { - return (r1.getRRsetType() == r2.getRRsetType() && - r1.getDClass() == r2.getDClass() && - r1.getName().equals(r2.getName())); -} - -/** - * Returns an array containing all records in the given section grouped into - * RRsets. - * @see RRset - * @see Section - */ -public RRset [] -getSectionRRsets(int section) { - if (sections[section] == null) - return emptyRRsetArray; - List sets = new LinkedList(); - Record [] recs = getSectionArray(section); - Set hash = new HashSet(); - for (int i = 0; i < recs.length; i++) { - Name name = recs[i].getName(); - boolean newset = true; - if (hash.contains(name)) { - for (int j = sets.size() - 1; j >= 0; j--) { - RRset set = (RRset) sets.get(j); - if (set.getType() == recs[i].getRRsetType() && - set.getDClass() == recs[i].getDClass() && - set.getName().equals(name)) - { - set.addRR(recs[i]); - newset = false; - break; - } - } - } - if (newset) { - RRset set = new RRset(recs[i]); - sets.add(set); - hash.add(name); - } - } - return (RRset []) sets.toArray(new RRset[sets.size()]); -} - -void -toWire(DNSOutput out) { - header.toWire(out); - Compression c = new Compression(); - for (int i = 0; i < 4; i++) { - if (sections[i] == null) - continue; - for (int j = 0; j < sections[i].size(); j++) { - Record rec = (Record)sections[i].get(j); - rec.toWire(out, i, c); - } - } -} - -/* Returns the number of records not successfully rendered. */ -private int -sectionToWire(DNSOutput out, int section, Compression c, - int maxLength) -{ - int n = sections[section].size(); - int pos = out.current(); - int rendered = 0; - int skipped = 0; - Record lastrec = null; - - for (int i = 0; i < n; i++) { - Record rec = (Record)sections[section].get(i); - if (section == Section.ADDITIONAL && rec instanceof OPTRecord) { - skipped++; - continue; - } - - if (lastrec != null && !sameSet(rec, lastrec)) { - pos = out.current(); - rendered = i; - } - lastrec = rec; - rec.toWire(out, section, c); - if (out.current() > maxLength) { - out.jump(pos); - return n - rendered + skipped; - } - } - return skipped; -} - -/* Returns true if the message could be rendered. */ -private boolean -toWire(DNSOutput out, int maxLength) { - if (maxLength < Header.LENGTH) - return false; - - Header newheader = null; - - int tempMaxLength = maxLength; - if (tsigkey != null) - tempMaxLength -= tsigkey.recordLength(); - - OPTRecord opt = getOPT(); - byte [] optBytes = null; - if (opt != null) { - optBytes = opt.toWire(Section.ADDITIONAL); - tempMaxLength -= optBytes.length; - } - - int startpos = out.current(); - header.toWire(out); - Compression c = new Compression(); - int flags = header.getFlagsByte(); - int additionalCount = 0; - for (int i = 0; i < 4; i++) { - int skipped; - if (sections[i] == null) - continue; - skipped = sectionToWire(out, i, c, tempMaxLength); - if (skipped != 0 && i != Section.ADDITIONAL) { - flags = Header.setFlag(flags, Flags.TC, true); - out.writeU16At(header.getCount(i) - skipped, - startpos + 4 + 2 * i); - for (int j = i + 1; j < Section.ADDITIONAL; j++) - out.writeU16At(0, startpos + 4 + 2 * j); - break; - } - if (i == Section.ADDITIONAL) - additionalCount = header.getCount(i) - skipped; - } - - if (optBytes != null) { - out.writeByteArray(optBytes); - additionalCount++; - } - - if (flags != header.getFlagsByte()) - out.writeU16At(flags, startpos + 2); - - if (additionalCount != header.getCount(Section.ADDITIONAL)) - out.writeU16At(additionalCount, startpos + 10); - - if (tsigkey != null) { - TSIGRecord tsigrec = tsigkey.generate(this, out.toByteArray(), - tsigerror, querytsig); - - tsigrec.toWire(out, Section.ADDITIONAL, c); - out.writeU16At(additionalCount + 1, startpos + 10); - } - - return true; -} - -/** - * Returns an array containing the wire format representation of the Message. - */ -public byte [] -toWire() { - DNSOutput out = new DNSOutput(); - toWire(out); - size = out.current(); - return out.toByteArray(); -} - -/** - * Returns an array containing the wire format representation of the Message - * with the specified maximum length. This will generate a truncated - * message (with the TC bit) if the message doesn't fit, and will also - * sign the message with the TSIG key set by a call to setTSIG(). This - * method may return null if the message could not be rendered at all; this - * could happen if maxLength is smaller than a DNS header, for example. - * @param maxLength The maximum length of the message. - * @return The wire format of the message, or null if the message could not be - * rendered into the specified length. - * @see Flags - * @see TSIG - */ -public byte [] -toWire(int maxLength) { - DNSOutput out = new DNSOutput(); - toWire(out, maxLength); - size = out.current(); - return out.toByteArray(); -} - -/** - * Sets the TSIG key and other necessary information to sign a message. - * @param key The TSIG key. - * @param error The value of the TSIG error field. - * @param querytsig If this is a response, the TSIG from the request. - */ -public void -setTSIG(TSIG key, int error, TSIGRecord querytsig) { - this.tsigkey = key; - this.tsigerror = error; - this.querytsig = querytsig; -} - -/** - * Returns the size of the message. Only valid if the message has been - * converted to or from wire format. - */ -public int -numBytes() { - return size; -} - -/** - * Converts the given section of the Message to a String. - * @see Section - */ -public String -sectionToString(int i) { - if (i > 3) - return null; - - StringBuffer sb = new StringBuffer(); - - Record [] records = getSectionArray(i); - for (int j = 0; j < records.length; j++) { - Record rec = records[j]; - if (i == Section.QUESTION) { - sb.append(";;\t" + rec.name); - sb.append(", type = " + Type.string(rec.type)); - sb.append(", class = " + DClass.string(rec.dclass)); - } - else - sb.append(rec); - sb.append("\n"); - } - return sb.toString(); -} - -/** - * Converts the Message to a String. - */ -public String -toString() { - StringBuffer sb = new StringBuffer(); - OPTRecord opt = getOPT(); - if (opt != null) - sb.append(header.toStringWithRcode(getRcode()) + "\n"); - else - sb.append(header + "\n"); - if (isSigned()) { - sb.append(";; TSIG "); - if (isVerified()) - sb.append("ok"); - else - sb.append("invalid"); - sb.append('\n'); - } - for (int i = 0; i < 4; i++) { - if (header.getOpcode() != Opcode.UPDATE) - sb.append(";; " + Section.longString(i) + ":\n"); - else - sb.append(";; " + Section.updString(i) + ":\n"); - sb.append(sectionToString(i) + "\n"); - } - sb.append(";; Message size: " + numBytes() + " bytes"); - return sb.toString(); -} - -/** - * Creates a copy of this Message. This is done by the Resolver before adding - * TSIG and OPT records, for example. - * @see Resolver - * @see TSIGRecord - * @see OPTRecord - */ -public Object -clone() { - Message m = new Message(); - for (int i = 0; i < sections.length; i++) { - if (sections[i] != null) - m.sections[i] = new LinkedList(sections[i]); - } - m.header = (Header) header.clone(); - m.size = size; - return m; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Mnemonic.java b/src/main/java/core/org/xbill/DNS/Mnemonic.java deleted file mode 100644 index b3b0d7a1..00000000 --- a/src/main/java/core/org/xbill/DNS/Mnemonic.java +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.HashMap; - -/** - * A utility class for converting between numeric codes and mnemonics - * for those codes. Mnemonics are case insensitive. - * - * @author Brian Wellington - */ - -class Mnemonic { - -private static Integer cachedInts[] = new Integer[64]; - -static { - for (int i = 0; i < cachedInts.length; i++) { - cachedInts[i] = i; - } -} - -/* Strings are case-sensitive. */ -static final int CASE_SENSITIVE = 1; - -/* Strings will be stored/searched for in uppercase. */ -static final int CASE_UPPER = 2; - -/* Strings will be stored/searched for in lowercase. */ -static final int CASE_LOWER = 3; - -private HashMap strings; -private HashMap values; -private String description; -private int wordcase; -private String prefix; -private int max; -private boolean numericok; - -/** - * Creates a new Mnemonic table. - * @param description A short description of the mnemonic to use when - * @param wordcase Whether to convert strings into uppercase, lowercase, - * or leave them unchanged. - * throwing exceptions. - */ -public -Mnemonic(String description, int wordcase) { - this.description = description; - this.wordcase = wordcase; - strings = new HashMap(); - values = new HashMap(); - max = Integer.MAX_VALUE; -} - -/** Sets the maximum numeric value */ -public void -setMaximum(int max) { - this.max = max; -} - -/** - * Sets the prefix to use when converting to and from values that don't - * have mnemonics. - */ -public void -setPrefix(String prefix) { - this.prefix = sanitize(prefix); -} - -/** - * Sets whether numeric values stored in strings are acceptable. - */ -public void -setNumericAllowed(boolean numeric) { - this.numericok = numeric; -} - -/** - * Converts an int into a possibly cached Integer. - */ -public static Integer -toInteger(int val) { - if (val >= 0 && val < cachedInts.length) - return (cachedInts[val]); - return val; -} - -/** - * Checks that a numeric value is within the range [0..max] - */ -public void -check(int val) { - if (val < 0 || val > max) { - throw new IllegalArgumentException(description + " " + val + - "is out of range"); - } -} - -/* Converts a String to the correct case. */ -private String -sanitize(String str) { - if (wordcase == CASE_UPPER) - return str.toUpperCase(); - else if (wordcase == CASE_LOWER) - return str.toLowerCase(); - return str; -} - -private int -parseNumeric(String s) { - try { - int val = Integer.parseInt(s); - if (val >= 0 && val <= max) - return val; - } - catch (NumberFormatException e) { - } - return -1; -} - -/** - * Defines the text representation of a numeric value. - * @param val The numeric value - * @param string The text string - */ -public void -add(int val, String str) { - check(val); - Integer value = toInteger(val); - str = sanitize(str); - strings.put(str, value); - values.put(value, str); -} - -/** - * Defines an additional text representation of a numeric value. This will - * be used by getValue(), but not getText(). - * @param val The numeric value - * @param string The text string - */ -public void -addAlias(int val, String str) { - check(val); - Integer value = toInteger(val); - str = sanitize(str); - strings.put(str, value); -} - -/** - * Copies all mnemonics from one table into another. - * @param val The numeric value - * @param string The text string - * @throws IllegalArgumentException The wordcases of the Mnemonics do not - * match. - */ -public void -addAll(Mnemonic source) { - if (wordcase != source.wordcase) - throw new IllegalArgumentException(source.description + - ": wordcases do not match"); - strings.putAll(source.strings); - values.putAll(source.values); -} - -/** - * Gets the text mnemonic corresponding to a numeric value. - * @param val The numeric value - * @return The corresponding text mnemonic. - */ -public String -getText(int val) { - check(val); - String str = (String) values.get(toInteger(val)); - if (str != null) - return str; - str = Integer.toString(val); - if (prefix != null) - return prefix + str; - return str; -} - -/** - * Gets the numeric value corresponding to a text mnemonic. - * @param str The text mnemonic - * @return The corresponding numeric value, or -1 if there is none - */ -public int -getValue(String str) { - str = sanitize(str); - Integer value = (Integer) strings.get(str); - if (value != null) { - return value.intValue(); - } - if (prefix != null) { - if (str.startsWith(prefix)) { - int val = parseNumeric(str.substring(prefix.length())); - if (val >= 0) { - return val; - } - } - } - if (numericok) { - return parseNumeric(str); - } - return -1; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/NAPTRRecord.java b/src/main/java/core/org/xbill/DNS/NAPTRRecord.java deleted file mode 100644 index da2ec6dc..00000000 --- a/src/main/java/core/org/xbill/DNS/NAPTRRecord.java +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2000-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * Name Authority Pointer Record - specifies rewrite rule, that when applied - * to an existing string will produce a new domain. - * - * @author Chuck Santos - */ - -public class NAPTRRecord extends Record { - -private static final long serialVersionUID = 5191232392044947002L; - -private int order, preference; -private byte [] flags, service, regexp; -private Name replacement; - -NAPTRRecord() {} - -Record -getObject() { - return new NAPTRRecord(); -} - -/** - * Creates an NAPTR Record from the given data - * @param order The order of this NAPTR. Records with lower order are - * preferred. - * @param preference The preference, used to select between records at the - * same order. - * @param flags The control aspects of the NAPTRRecord. - * @param service The service or protocol available down the rewrite path. - * @param regexp The regular/substitution expression. - * @param replacement The domain-name to query for the next DNS resource - * record, depending on the value of the flags field. - * @throws IllegalArgumentException One of the strings has invalid escapes - */ -public -NAPTRRecord(Name name, int dclass, long ttl, int order, int preference, - String flags, String service, String regexp, Name replacement) -{ - super(name, Type.NAPTR, dclass, ttl); - this.order = checkU16("order", order); - this.preference = checkU16("preference", preference); - try { - this.flags = byteArrayFromString(flags); - this.service = byteArrayFromString(service); - this.regexp = byteArrayFromString(regexp); - } - catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } - this.replacement = checkName("replacement", replacement); -} - -void -rrFromWire(DNSInput in) throws IOException { - order = in.readU16(); - preference = in.readU16(); - flags = in.readCountedString(); - service = in.readCountedString(); - regexp = in.readCountedString(); - replacement = new Name(in); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - order = st.getUInt16(); - preference = st.getUInt16(); - try { - flags = byteArrayFromString(st.getString()); - service = byteArrayFromString(st.getString()); - regexp = byteArrayFromString(st.getString()); - } - catch (TextParseException e) { - throw st.exception(e.getMessage()); - } - replacement = st.getName(origin); -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(order); - sb.append(" "); - sb.append(preference); - sb.append(" "); - sb.append(byteArrayToString(flags, true)); - sb.append(" "); - sb.append(byteArrayToString(service, true)); - sb.append(" "); - sb.append(byteArrayToString(regexp, true)); - sb.append(" "); - sb.append(replacement); - return sb.toString(); -} - -/** Returns the order */ -public int -getOrder() { - return order; -} - -/** Returns the preference */ -public int -getPreference() { - return preference; -} - -/** Returns flags */ -public String -getFlags() { - return byteArrayToString(flags, false); -} - -/** Returns service */ -public String -getService() { - return byteArrayToString(service, false); -} - -/** Returns regexp */ -public String -getRegexp() { - return byteArrayToString(regexp, false); -} - -/** Returns the replacement domain-name */ -public Name -getReplacement() { - return replacement; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(order); - out.writeU16(preference); - out.writeCountedString(flags); - out.writeCountedString(service); - out.writeCountedString(regexp); - replacement.toWire(out, null, canonical); -} - -public Name -getAdditionalName() { - return replacement; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/NSAPRecord.java b/src/main/java/core/org/xbill/DNS/NSAPRecord.java deleted file mode 100644 index a6b2031d..00000000 --- a/src/main/java/core/org/xbill/DNS/NSAPRecord.java +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import org.xbill.DNS.utils.*; - -/** - * NSAP Address Record. - * - * @author Brian Wellington - */ - -public class NSAPRecord extends Record { - -private static final long serialVersionUID = -1037209403185658593L; - -private byte [] address; - -NSAPRecord() {} - -Record -getObject() { - return new NSAPRecord(); -} - -private static final byte [] -checkAndConvertAddress(String address) { - if (!address.substring(0, 2).equalsIgnoreCase("0x")) { - return null; - } - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - boolean partial = false; - int current = 0; - for (int i = 2; i < address.length(); i++) { - char c = address.charAt(i); - if (c == '.') { - continue; - } - int value = Character.digit(c, 16); - if (value == -1) { - return null; - } - if (partial) { - current += value; - bytes.write(current); - partial = false; - } else { - current = value << 4; - partial = true; - } - - } - if (partial) { - return null; - } - return bytes.toByteArray(); -} - -/** - * Creates an NSAP Record from the given data - * @param address The NSAP address. - * @throws IllegalArgumentException The address is not a valid NSAP address. - */ -public -NSAPRecord(Name name, int dclass, long ttl, String address) { - super(name, Type.NSAP, dclass, ttl); - this.address = checkAndConvertAddress(address); - if (this.address == null) { - throw new IllegalArgumentException("invalid NSAP address " + - address); - } -} - -void -rrFromWire(DNSInput in) throws IOException { - address = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - String addr = st.getString(); - this.address = checkAndConvertAddress(addr); - if (this.address == null) - throw st.exception("invalid NSAP address " + addr); -} - -/** - * Returns the NSAP address. - */ -public String -getAddress() { - return byteArrayToString(address, false); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeByteArray(address); -} - -String -rrToString() { - return "0x" + base16.toString(address); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/NSAP_PTRRecord.java b/src/main/java/core/org/xbill/DNS/NSAP_PTRRecord.java deleted file mode 100644 index ecc609f4..00000000 --- a/src/main/java/core/org/xbill/DNS/NSAP_PTRRecord.java +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * NSAP Pointer Record - maps a domain name representing an NSAP Address to - * a hostname. - * - * @author Brian Wellington - */ - -public class NSAP_PTRRecord extends SingleNameBase { - -private static final long serialVersionUID = 2386284746382064904L; - -NSAP_PTRRecord() {} - -Record -getObject() { - return new NSAP_PTRRecord(); -} - -/** - * Creates a new NSAP_PTR Record with the given data - * @param target The name of the host with this address - */ -public -NSAP_PTRRecord(Name name, int dclass, long ttl, Name target) { - super(name, Type.NSAP_PTR, dclass, ttl, target, "target"); -} - -/** Gets the target of the NSAP_PTR Record */ -public Name -getTarget() { - return getSingleName(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/NSEC3PARAMRecord.java b/src/main/java/core/org/xbill/DNS/NSEC3PARAMRecord.java deleted file mode 100644 index d663a62c..00000000 --- a/src/main/java/core/org/xbill/DNS/NSEC3PARAMRecord.java +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.IOException; -import java.security.NoSuchAlgorithmException; - -import org.xbill.DNS.utils.base16; - -/** - * Next SECure name 3 Parameters - this record contains the parameters (hash - * algorithm, salt, iterations) used for a valid, complete NSEC3 chain present - * in a zone. Zones signed using NSEC3 must include this record at the zone apex - * to inform authoritative servers that NSEC3 is being used with the given - * parameters. - * - * @author Brian Wellington - * @author David Blacka - */ - -public class NSEC3PARAMRecord extends Record { - -private static final long serialVersionUID = -8689038598776316533L; - -private int hashAlg; -private int flags; -private int iterations; -private byte salt[]; - -NSEC3PARAMRecord() {} - -Record getObject() { - return new NSEC3PARAMRecord(); -} - -/** - * Creates an NSEC3PARAM record from the given data. - * - * @param name The ownername of the NSEC3PARAM record (generally the zone name). - * @param dclass The class. - * @param ttl The TTL. - * @param hashAlg The hash algorithm. - * @param flags The value of the flags field. - * @param iterations The number of hash iterations. - * @param salt The salt to use (may be null). - */ -public NSEC3PARAMRecord(Name name, int dclass, long ttl, int hashAlg, - int flags, int iterations, byte [] salt) -{ - super(name, Type.NSEC3PARAM, dclass, ttl); - this.hashAlg = checkU8("hashAlg", hashAlg); - this.flags = checkU8("flags", flags); - this.iterations = checkU16("iterations", iterations); - - if (salt != null) { - if (salt.length > 255) - throw new IllegalArgumentException("Invalid salt " + - "length"); - if (salt.length > 0) { - this.salt = new byte[salt.length]; - System.arraycopy(salt, 0, this.salt, 0, salt.length); - } - } -} - -void -rrFromWire(DNSInput in) throws IOException { - hashAlg = in.readU8(); - flags = in.readU8(); - iterations = in.readU16(); - - int salt_length = in.readU8(); - if (salt_length > 0) - salt = in.readByteArray(salt_length); - else - salt = null; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU8(hashAlg); - out.writeU8(flags); - out.writeU16(iterations); - - if (salt != null) { - out.writeU8(salt.length); - out.writeByteArray(salt); - } else - out.writeU8(0); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException -{ - hashAlg = st.getUInt8(); - flags = st.getUInt8(); - iterations = st.getUInt16(); - - String s = st.getString(); - if (s.equals("-")) - salt = null; - else { - st.unget(); - salt = st.getHexString(); - if (salt.length > 255) - throw st.exception("salt value too long"); - } -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(hashAlg); - sb.append(' '); - sb.append(flags); - sb.append(' '); - sb.append(iterations); - sb.append(' '); - if (salt == null) - sb.append('-'); - else - sb.append(base16.toString(salt)); - - return sb.toString(); -} - -/** Returns the hash algorithm */ -public int -getHashAlgorithm() { - return hashAlg; -} - -/** Returns the flags */ -public int -getFlags() { - return flags; -} - -/** Returns the number of iterations */ -public int -getIterations() { - return iterations; -} - -/** Returns the salt */ -public byte [] -getSalt() -{ - return salt; -} - -/** - * Hashes a name with the parameters of this NSEC3PARAM record. - * @param name The name to hash - * @return The hashed version of the name - * @throws NoSuchAlgorithmException The hash algorithm is unknown. - */ -public byte [] -hashName(Name name) throws NoSuchAlgorithmException -{ - return NSEC3Record.hashName(name, hashAlg, iterations, salt); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/NSEC3Record.java b/src/main/java/core/org/xbill/DNS/NSEC3Record.java deleted file mode 100644 index aa086b8f..00000000 --- a/src/main/java/core/org/xbill/DNS/NSEC3Record.java +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.security.*; - -import org.xbill.DNS.utils.*; - -/** - * Next SECure name 3 - this record contains the next hashed name in an - * ordered list of hashed names in the zone, and a set of types for which - * records exist for this name. The presence of this record in a response - * signifies a negative response from a DNSSEC-signed zone. - * - * This replaces the NSEC and NXT records, when used. - * - * @author Brian Wellington - * @author David Blacka - */ - -public class NSEC3Record extends Record { - -public static class Flags { - /** - * NSEC3 flags identifiers. - */ - - private Flags() {} - - /** Unsigned delegation are not included in the NSEC3 chain. - * - */ - public static final int OPT_OUT = 0x01; -} - -public static class Digest { - private Digest() {} - - /** SHA-1 */ - public static final int SHA1 = 1; -} - -public static final int SHA1_DIGEST_ID = Digest.SHA1; - -private static final long serialVersionUID = -7123504635968932855L; - -private int hashAlg; -private int flags; -private int iterations; -private byte [] salt; -private byte [] next; -private TypeBitmap types; - -private static final base32 b32 = new base32(base32.Alphabet.BASE32HEX, - false, false); - -NSEC3Record() {} - -Record getObject() { - return new NSEC3Record(); -} - -/** - * Creates an NSEC3 record from the given data. - * - * @param name The ownername of the NSEC3 record (base32'd hash plus zonename). - * @param dclass The class. - * @param ttl The TTL. - * @param hashAlg The hash algorithm. - * @param flags The value of the flags field. - * @param iterations The number of hash iterations. - * @param salt The salt to use (may be null). - * @param next The next hash (may not be null). - * @param types The types present at the original ownername. - */ -public NSEC3Record(Name name, int dclass, long ttl, int hashAlg, - int flags, int iterations, byte [] salt, byte [] next, - int [] types) -{ - super(name, Type.NSEC3, dclass, ttl); - this.hashAlg = checkU8("hashAlg", hashAlg); - this.flags = checkU8("flags", flags); - this.iterations = checkU16("iterations", iterations); - - if (salt != null) { - if (salt.length > 255) - throw new IllegalArgumentException("Invalid salt"); - if (salt.length > 0) { - this.salt = new byte[salt.length]; - System.arraycopy(salt, 0, this.salt, 0, salt.length); - } - } - - if (next.length > 255) { - throw new IllegalArgumentException("Invalid next hash"); - } - this.next = new byte[next.length]; - System.arraycopy(next, 0, this.next, 0, next.length); - this.types = new TypeBitmap(types); -} - -void -rrFromWire(DNSInput in) throws IOException { - hashAlg = in.readU8(); - flags = in.readU8(); - iterations = in.readU16(); - - int salt_length = in.readU8(); - if (salt_length > 0) - salt = in.readByteArray(salt_length); - else - salt = null; - - int next_length = in.readU8(); - next = in.readByteArray(next_length); - types = new TypeBitmap(in); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU8(hashAlg); - out.writeU8(flags); - out.writeU16(iterations); - - if (salt != null) { - out.writeU8(salt.length); - out.writeByteArray(salt); - } else - out.writeU8(0); - - out.writeU8(next.length); - out.writeByteArray(next); - types.toWire(out); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - hashAlg = st.getUInt8(); - flags = st.getUInt8(); - iterations = st.getUInt16(); - - String s = st.getString(); - if (s.equals("-")) - salt = null; - else { - st.unget(); - salt = st.getHexString(); - if (salt.length > 255) - throw st.exception("salt value too long"); - } - - next = st.getBase32String(b32); - types = new TypeBitmap(st); -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(hashAlg); - sb.append(' '); - sb.append(flags); - sb.append(' '); - sb.append(iterations); - sb.append(' '); - if (salt == null) - sb.append('-'); - else - sb.append(base16.toString(salt)); - sb.append(' '); - sb.append(b32.toString(next)); - - if (!types.empty()) { - sb.append(' '); - sb.append(types.toString()); - } - - return sb.toString(); -} - -/** Returns the hash algorithm */ -public int -getHashAlgorithm() { - return hashAlg; -} - -/** Returns the flags */ -public int -getFlags() { - return flags; -} - -/** Returns the number of iterations */ -public int -getIterations() { - return iterations; -} - -/** Returns the salt */ -public byte [] -getSalt() -{ - return salt; -} - -/** Returns the next hash */ -public byte [] -getNext() { - return next; -} - - /** Returns the set of types defined for this name */ -public int [] -getTypes() { - return types.toArray(); -} - -/** Returns whether a specific type is in the set of types. */ -public boolean -hasType(int type) -{ - return types.contains(type); -} - -static byte [] -hashName(Name name, int hashAlg, int iterations, byte [] salt) -throws NoSuchAlgorithmException -{ - MessageDigest digest; - switch (hashAlg) { - case Digest.SHA1: - digest = MessageDigest.getInstance("sha-1"); - break; - default: - throw new NoSuchAlgorithmException("Unknown NSEC3 algorithm" + - "identifier: " + - hashAlg); - } - byte [] hash = null; - for (int i = 0; i <= iterations; i++) { - digest.reset(); - if (i == 0) - digest.update(name.toWireCanonical()); - else - digest.update(hash); - if (salt != null) - digest.update(salt); - hash = digest.digest(); - } - return hash; -} - -/** - * Hashes a name with the parameters of this NSEC3 record. - * @param name The name to hash - * @return The hashed version of the name - * @throws NoSuchAlgorithmException The hash algorithm is unknown. - */ -public byte [] -hashName(Name name) throws NoSuchAlgorithmException -{ - return hashName(name, hashAlg, iterations, salt); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/NSECRecord.java b/src/main/java/core/org/xbill/DNS/NSECRecord.java deleted file mode 100644 index e523e375..00000000 --- a/src/main/java/core/org/xbill/DNS/NSECRecord.java +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * Next SECure name - this record contains the following name in an - * ordered list of names in the zone, and a set of types for which - * records exist for this name. The presence of this record in a response - * signifies a negative response from a DNSSEC-signed zone. - * - * This replaces the NXT record. - * - * @author Brian Wellington - * @author David Blacka - */ - -public class NSECRecord extends Record { - -private static final long serialVersionUID = -5165065768816265385L; - -private Name next; -private TypeBitmap types; - -NSECRecord() {} - -Record -getObject() { - return new NSECRecord(); -} - -/** - * Creates an NSEC Record from the given data. - * @param next The following name in an ordered list of the zone - * @param types An array containing the types present. - */ -public -NSECRecord(Name name, int dclass, long ttl, Name next, int [] types) { - super(name, Type.NSEC, dclass, ttl); - this.next = checkName("next", next); - for (int i = 0; i < types.length; i++) { - Type.check(types[i]); - } - this.types = new TypeBitmap(types); -} - -void -rrFromWire(DNSInput in) throws IOException { - next = new Name(in); - types = new TypeBitmap(in); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - // Note: The next name is not lowercased. - next.toWire(out, null, false); - types.toWire(out); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - next = st.getName(origin); - types = new TypeBitmap(st); -} - -/** Converts rdata to a String */ -String -rrToString() -{ - StringBuffer sb = new StringBuffer(); - sb.append(next); - if (!types.empty()) { - sb.append(' '); - sb.append(types.toString()); - } - return sb.toString(); -} - -/** Returns the next name */ -public Name -getNext() { - return next; -} - -/** Returns the set of types defined for this name */ -public int [] -getTypes() { - return types.toArray(); -} - -/** Returns whether a specific type is in the set of types. */ -public boolean -hasType(int type) { - return types.contains(type); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/NSIDOption.java b/src/main/java/core/org/xbill/DNS/NSIDOption.java deleted file mode 100644 index 7bcbcd57..00000000 --- a/src/main/java/core/org/xbill/DNS/NSIDOption.java +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * The Name Server Identifier Option, define in RFC 5001. - * - * @see OPTRecord - * - * @author Brian Wellington - */ -public class NSIDOption extends GenericEDNSOption { - -private static final long serialVersionUID = 74739759292589056L; - -NSIDOption() { - super(EDNSOption.Code.NSID); -} - -/** - * Construct an NSID option. - * @param data The contents of the option. - */ -public -NSIDOption(byte [] data) { - super(EDNSOption.Code.NSID, data); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/NSRecord.java b/src/main/java/core/org/xbill/DNS/NSRecord.java deleted file mode 100644 index 2908da4d..00000000 --- a/src/main/java/core/org/xbill/DNS/NSRecord.java +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Name Server Record - contains the name server serving the named zone - * - * @author Brian Wellington - */ - -public class NSRecord extends SingleCompressedNameBase { - -private static final long serialVersionUID = 487170758138268838L; - -NSRecord() {} - -Record -getObject() { - return new NSRecord(); -} - -/** - * Creates a new NS Record with the given data - * @param target The name server for the given domain - */ -public -NSRecord(Name name, int dclass, long ttl, Name target) { - super(name, Type.NS, dclass, ttl, target, "target"); -} - -/** Gets the target of the NS Record */ -public Name -getTarget() { - return getSingleName(); -} - -public Name -getAdditionalName() { - return getSingleName(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/NULLRecord.java b/src/main/java/core/org/xbill/DNS/NULLRecord.java deleted file mode 100644 index fa46d61d..00000000 --- a/src/main/java/core/org/xbill/DNS/NULLRecord.java +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * The NULL Record. This has no defined purpose, but can be used to - * hold arbitrary data. - * - * @author Brian Wellington - */ - -public class NULLRecord extends Record { - -private static final long serialVersionUID = -5796493183235216538L; - -private byte [] data; - -NULLRecord() {} - -Record -getObject() { - return new NULLRecord(); -} - -/** - * Creates a NULL record from the given data. - * @param data The contents of the record. - */ -public -NULLRecord(Name name, int dclass, long ttl, byte [] data) { - super(name, Type.NULL, dclass, ttl); - - if (data.length > 0xFFFF) { - throw new IllegalArgumentException("data must be <65536 bytes"); - } - this.data = data; -} - -void -rrFromWire(DNSInput in) throws IOException { - data = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - throw st.exception("no defined text format for NULL records"); -} - -String -rrToString() { - return unknownToString(data); -} - -/** Returns the contents of this record. */ -public byte [] -getData() { - return data; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeByteArray(data); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/NXTRecord.java b/src/main/java/core/org/xbill/DNS/NXTRecord.java deleted file mode 100644 index ad04e010..00000000 --- a/src/main/java/core/org/xbill/DNS/NXTRecord.java +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; - -/** - * Next name - this record contains the following name in an ordered list - * of names in the zone, and a set of types for which records exist for - * this name. The presence of this record in a response signifies a - * failed query for data in a DNSSEC-signed zone. - * - * @author Brian Wellington - */ - -public class NXTRecord extends Record { - -private static final long serialVersionUID = -8851454400765507520L; - -private Name next; -private BitSet bitmap; - -NXTRecord() {} - -Record -getObject() { - return new NXTRecord(); -} - -/** - * Creates an NXT Record from the given data - * @param next The following name in an ordered list of the zone - * @param bitmap The set of type for which records exist at this name -*/ -public -NXTRecord(Name name, int dclass, long ttl, Name next, BitSet bitmap) { - super(name, Type.NXT, dclass, ttl); - this.next = checkName("next", next); - this.bitmap = bitmap; -} - -void -rrFromWire(DNSInput in) throws IOException { - next = new Name(in); - bitmap = new BitSet(); - int bitmapLength = in.remaining(); - for (int i = 0; i < bitmapLength; i++) { - int t = in.readU8(); - for (int j = 0; j < 8; j++) - if ((t & (1 << (7 - j))) != 0) - bitmap.set(i * 8 + j); - } -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - next = st.getName(origin); - bitmap = new BitSet(); - while (true) { - Tokenizer.Token t = st.get(); - if (!t.isString()) - break; - int typecode = Type.value(t.value, true); - if (typecode <= 0 || typecode > 128) - throw st.exception("Invalid type: " + t.value); - bitmap.set(typecode); - } - st.unget(); -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(next); - int length = bitmap.length(); - for (short i = 0; i < length; i++) - if (bitmap.get(i)) { - sb.append(" "); - sb.append(Type.string(i)); - } - return sb.toString(); -} - -/** Returns the next name */ -public Name -getNext() { - return next; -} - -/** Returns the set of types defined for this name */ -public BitSet -getBitmap() { - return bitmap; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - next.toWire(out, null, canonical); - int length = bitmap.length(); - for (int i = 0, t = 0; i < length; i++) { - t |= (bitmap.get(i) ? (1 << (7 - i % 8)) : 0); - if (i % 8 == 7 || i == length - 1) { - out.writeU8(t); - t = 0; - } - } -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Name.java b/src/main/java/core/org/xbill/DNS/Name.java deleted file mode 100644 index c91ce4ff..00000000 --- a/src/main/java/core/org/xbill/DNS/Name.java +++ /dev/null @@ -1,860 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.text.*; - -/** - * A representation of a domain name. It may either be absolute (fully - * qualified) or relative. - * - * @author Brian Wellington - */ - -public class Name implements Comparable, Serializable { - -private static final long serialVersionUID = -7257019940971525644L; - -private static final int LABEL_NORMAL = 0; -private static final int LABEL_COMPRESSION = 0xC0; -private static final int LABEL_MASK = 0xC0; - -/* The name data */ -private byte [] name; - -/* - * Effectively an 8 byte array, where the low order byte stores the number - * of labels and the 7 higher order bytes store per-label offsets. - */ -private long offsets; - -/* Precomputed hashcode. */ -private int hashcode; - -private static final byte [] emptyLabel = new byte[] {(byte)0}; -private static final byte [] wildLabel = new byte[] {(byte)1, (byte)'*'}; - -/** The root name */ -public static final Name root; - -/** The root name */ -public static final Name empty; - -/** The maximum length of a Name */ -private static final int MAXNAME = 255; - -/** The maximum length of a label a Name */ -private static final int MAXLABEL = 63; - -/** The maximum number of labels in a Name */ -private static final int MAXLABELS = 128; - -/** The maximum number of cached offsets */ -private static final int MAXOFFSETS = 7; - -/* Used for printing non-printable characters */ -private static final DecimalFormat byteFormat = new DecimalFormat(); - -/* Used to efficiently convert bytes to lowercase */ -private static final byte lowercase[] = new byte[256]; - -/* Used in wildcard names. */ -private static final Name wild; - -static { - byteFormat.setMinimumIntegerDigits(3); - for (int i = 0; i < lowercase.length; i++) { - if (i < 'A' || i > 'Z') - lowercase[i] = (byte)i; - else - lowercase[i] = (byte)(i - 'A' + 'a'); - } - root = new Name(); - root.appendSafe(emptyLabel, 0, 1); - empty = new Name(); - empty.name = new byte[0]; - wild = new Name(); - wild.appendSafe(wildLabel, 0, 1); -} - -private -Name() { -} - -private final void -setoffset(int n, int offset) { - if (n >= MAXOFFSETS) - return; - int shift = 8 * (7 - n); - offsets &= (~(0xFFL << shift)); - offsets |= ((long)offset << shift); -} - -private final int -offset(int n) { - if (n == 0 && getlabels() == 0) - return 0; - if (n < 0 || n >= getlabels()) - throw new IllegalArgumentException("label out of range"); - if (n < MAXOFFSETS) { - int shift = 8 * (7 - n); - return ((int)(offsets >>> shift) & 0xFF); - } else { - int pos = offset(MAXOFFSETS - 1); - for (int i = MAXOFFSETS - 1; i < n; i++) - pos += (name[pos] + 1); - return (pos); - } -} - -private final void -setlabels(int labels) { - offsets &= ~(0xFF); - offsets |= labels; -} - -private final int -getlabels() { - return (int)(offsets & 0xFF); -} - -private static final void -copy(Name src, Name dst) { - if (src.offset(0) == 0) { - dst.name = src.name; - dst.offsets = src.offsets; - } else { - int offset0 = src.offset(0); - int namelen = src.name.length - offset0; - int labels = src.labels(); - dst.name = new byte[namelen]; - System.arraycopy(src.name, offset0, dst.name, 0, namelen); - for (int i = 0; i < labels && i < MAXOFFSETS; i++) - dst.setoffset(i, src.offset(i) - offset0); - dst.setlabels(labels); - } -} - -private final void -append(byte [] array, int start, int n) throws NameTooLongException { - int length = (name == null ? 0 : (name.length - offset(0))); - int alength = 0; - for (int i = 0, pos = start; i < n; i++) { - int len = array[pos]; - if (len > MAXLABEL) - throw new IllegalStateException("invalid label"); - len++; - pos += len; - alength += len; - } - int newlength = length + alength; - if (newlength > MAXNAME) - throw new NameTooLongException(); - int labels = getlabels(); - int newlabels = labels + n; - if (newlabels > MAXLABELS) - throw new IllegalStateException("too many labels"); - byte [] newname = new byte[newlength]; - if (length != 0) - System.arraycopy(name, offset(0), newname, 0, length); - System.arraycopy(array, start, newname, length, alength); - name = newname; - for (int i = 0, pos = length; i < n; i++) { - setoffset(labels + i, pos); - pos += (newname[pos] + 1); - } - setlabels(newlabels); -} - -private static TextParseException -parseException(String str, String message) { - return new TextParseException("'" + str + "': " + message); -} - -private final void -appendFromString(String fullName, byte [] array, int start, int n) -throws TextParseException -{ - try { - append(array, start, n); - } - catch (NameTooLongException e) { - throw parseException(fullName, "Name too long"); - } -} - -private final void -appendSafe(byte [] array, int start, int n) { - try { - append(array, start, n); - } - catch (NameTooLongException e) { - } -} - -/** - * Create a new name from a string and an origin. This does not automatically - * make the name absolute; it will be absolute if it has a trailing dot or an - * absolute origin is appended. - * @param s The string to be converted - * @param origin If the name is not absolute, the origin to be appended. - * @throws TextParseException The name is invalid. - */ -public -Name(String s, Name origin) throws TextParseException { - if (s.equals("")) - throw parseException(s, "empty name"); - else if (s.equals("@")) { - if (origin == null) - copy(empty, this); - else - copy(origin, this); - return; - } else if (s.equals(".")) { - copy(root, this); - return; - } - int labelstart = -1; - int pos = 1; - byte [] label = new byte[MAXLABEL + 1]; - boolean escaped = false; - int digits = 0; - int intval = 0; - boolean absolute = false; - for (int i = 0; i < s.length(); i++) { - byte b = (byte) s.charAt(i); - if (escaped) { - if (b >= '0' && b <= '9' && digits < 3) { - digits++; - intval *= 10; - intval += (b - '0'); - if (intval > 255) - throw parseException(s, "bad escape"); - if (digits < 3) - continue; - b = (byte) intval; - } - else if (digits > 0 && digits < 3) - throw parseException(s, "bad escape"); - if (pos > MAXLABEL) - throw parseException(s, "label too long"); - labelstart = pos; - label[pos++] = b; - escaped = false; - } else if (b == '\\') { - escaped = true; - digits = 0; - intval = 0; - } else if (b == '.') { - if (labelstart == -1) - throw parseException(s, "invalid empty label"); - label[0] = (byte)(pos - 1); - appendFromString(s, label, 0, 1); - labelstart = -1; - pos = 1; - } else { - if (labelstart == -1) - labelstart = i; - if (pos > MAXLABEL) - throw parseException(s, "label too long"); - label[pos++] = b; - } - } - if (digits > 0 && digits < 3) - throw parseException(s, "bad escape"); - if (escaped) - throw parseException(s, "bad escape"); - if (labelstart == -1) { - appendFromString(s, emptyLabel, 0, 1); - absolute = true; - } else { - label[0] = (byte)(pos - 1); - appendFromString(s, label, 0, 1); - } - if (origin != null && !absolute) - appendFromString(s, origin.name, origin.offset(0), - origin.getlabels()); -} - -/** - * Create a new name from a string. This does not automatically make the name - * absolute; it will be absolute if it has a trailing dot. - * @param s The string to be converted - * @throws TextParseException The name is invalid. - */ -public -Name(String s) throws TextParseException { - this(s, null); -} - -/** - * Create a new name from a string and an origin. This does not automatically - * make the name absolute; it will be absolute if it has a trailing dot or an - * absolute origin is appended. This is identical to the constructor, except - * that it will avoid creating new objects in some cases. - * @param s The string to be converted - * @param origin If the name is not absolute, the origin to be appended. - * @throws TextParseException The name is invalid. - */ -public static Name -fromString(String s, Name origin) throws TextParseException { - if (s.equals("@") && origin != null) - return origin; - else if (s.equals(".")) - return (root); - - return new Name(s, origin); -} - -/** - * Create a new name from a string. This does not automatically make the name - * absolute; it will be absolute if it has a trailing dot. This is identical - * to the constructor, except that it will avoid creating new objects in some - * cases. - * @param s The string to be converted - * @throws TextParseException The name is invalid. - */ -public static Name -fromString(String s) throws TextParseException { - return fromString(s, null); -} - -/** - * Create a new name from a constant string. This should only be used when - the name is known to be good - that is, when it is constant. - * @param s The string to be converted - * @throws IllegalArgumentException The name is invalid. - */ -public static Name -fromConstantString(String s) { - try { - return fromString(s, null); - } - catch (TextParseException e) { - throw new IllegalArgumentException("Invalid name '" + s + "'"); - } -} - -/** - * Create a new name from DNS a wire format message - * @param in A stream containing the DNS message which is currently - * positioned at the start of the name to be read. - */ -public -Name(DNSInput in) throws WireParseException { - int len, pos; - boolean done = false; - byte [] label = new byte[MAXLABEL + 1]; - boolean savedState = false; - - while (!done) { - len = in.readU8(); - switch (len & LABEL_MASK) { - case LABEL_NORMAL: - if (getlabels() >= MAXLABELS) - throw new WireParseException("too many labels"); - if (len == 0) { - append(emptyLabel, 0, 1); - done = true; - } else { - label[0] = (byte)len; - in.readByteArray(label, 1, len); - append(label, 0, 1); - } - break; - case LABEL_COMPRESSION: - pos = in.readU8(); - pos += ((len & ~LABEL_MASK) << 8); - if (Options.check("verbosecompression")) - System.err.println("currently " + in.current() + - ", pointer to " + pos); - - if (pos >= in.current() - 2) - throw new WireParseException("bad compression"); - if (!savedState) { - in.save(); - savedState = true; - } - in.jump(pos); - if (Options.check("verbosecompression")) - System.err.println("current name '" + this + - "', seeking to " + pos); - break; - default: - throw new WireParseException("bad label type"); - } - } - if (savedState) { - in.restore(); - } -} - -/** - * Create a new name from DNS wire format - * @param b A byte array containing the wire format of the name. - */ -public -Name(byte [] b) throws IOException { - this(new DNSInput(b)); -} - -/** - * Create a new name by removing labels from the beginning of an existing Name - * @param src An existing Name - * @param n The number of labels to remove from the beginning in the copy - */ -public -Name(Name src, int n) { - int slabels = src.labels(); - if (n > slabels) - throw new IllegalArgumentException("attempted to remove too " + - "many labels"); - name = src.name; - setlabels(slabels - n); - for (int i = 0; i < MAXOFFSETS && i < slabels - n; i++) - setoffset(i, src.offset(i + n)); -} - -/** - * Creates a new name by concatenating two existing names. - * @param prefix The prefix name. - * @param suffix The suffix name. - * @return The concatenated name. - * @throws NameTooLongException The name is too long. - */ -public static Name -concatenate(Name prefix, Name suffix) throws NameTooLongException { - if (prefix.isAbsolute()) - return (prefix); - Name newname = new Name(); - copy(prefix, newname); - newname.append(suffix.name, suffix.offset(0), suffix.getlabels()); - return newname; -} - -/** - * If this name is a subdomain of origin, return a new name relative to - * origin with the same value. Otherwise, return the existing name. - * @param origin The origin to remove. - * @return The possibly relativized name. - */ -public Name -relativize(Name origin) { - if (origin == null || !subdomain(origin)) - return this; - Name newname = new Name(); - copy(this, newname); - int length = length() - origin.length(); - int labels = newname.labels() - origin.labels(); - newname.setlabels(labels); - newname.name = new byte[length]; - System.arraycopy(name, offset(0), newname.name, 0, length); - return newname; -} - -/** - * Generates a new Name with the first n labels replaced by a wildcard - * @return The wildcard name - */ -public Name -wild(int n) { - if (n < 1) - throw new IllegalArgumentException("must replace 1 or more " + - "labels"); - try { - Name newname = new Name(); - copy(wild, newname); - newname.append(name, offset(n), getlabels() - n); - return newname; - } - catch (NameTooLongException e) { - throw new IllegalStateException - ("Name.wild: concatenate failed"); - } -} - -/** - * Returns a canonicalized version of the Name (all lowercase). This may be - * the same name, if the input Name is already canonical. - */ -public Name -canonicalize() { - boolean canonical = true; - for (int i = 0; i < name.length; i++) { - if (lowercase[name[i] & 0xFF] != name[i]) { - canonical = false; - break; - } - } - if (canonical) - return this; - - Name newname = new Name(); - newname.appendSafe(name, offset(0), getlabels()); - for (int i = 0; i < newname.name.length; i++) - newname.name[i] = lowercase[newname.name[i] & 0xFF]; - - return newname; -} - -/** - * Generates a new Name to be used when following a DNAME. - * @param dname The DNAME record to follow. - * @return The constructed name. - * @throws NameTooLongException The resulting name is too long. - */ -public Name -fromDNAME(DNAMERecord dname) throws NameTooLongException { - Name dnameowner = dname.getName(); - Name dnametarget = dname.getTarget(); - if (!subdomain(dnameowner)) - return null; - - int plabels = labels() - dnameowner.labels(); - int plength = length() - dnameowner.length(); - int pstart = offset(0); - - int dlabels = dnametarget.labels(); - int dlength = dnametarget.length(); - - if (plength + dlength > MAXNAME) - throw new NameTooLongException(); - - Name newname = new Name(); - newname.setlabels(plabels + dlabels); - newname.name = new byte[plength + dlength]; - System.arraycopy(name, pstart, newname.name, 0, plength); - System.arraycopy(dnametarget.name, 0, newname.name, plength, dlength); - - for (int i = 0, pos = 0; i < MAXOFFSETS && i < plabels + dlabels; i++) { - newname.setoffset(i, pos); - pos += (newname.name[pos] + 1); - } - return newname; -} - -/** - * Is this name a wildcard? - */ -public boolean -isWild() { - if (labels() == 0) - return false; - return (name[0] == (byte)1 && name[1] == (byte)'*'); -} - -/** - * Is this name absolute? - */ -public boolean -isAbsolute() { - int nlabels = labels(); - if (nlabels == 0) - return false; - return name[offset(nlabels - 1)] == 0; -} - -/** - * The length of the name. - */ -public short -length() { - if (getlabels() == 0) - return 0; - return (short)(name.length - offset(0)); -} - -/** - * The number of labels in the name. - */ -public int -labels() { - return getlabels(); -} - -/** - * Is the current Name a subdomain of the specified name? - */ -public boolean -subdomain(Name domain) { - int labels = labels(); - int dlabels = domain.labels(); - if (dlabels > labels) - return false; - if (dlabels == labels) - return equals(domain); - return domain.equals(name, offset(labels - dlabels)); -} - -private String -byteString(byte [] array, int pos) { - StringBuffer sb = new StringBuffer(); - int len = array[pos++]; - for (int i = pos; i < pos + len; i++) { - int b = array[i] & 0xFF; - if (b <= 0x20 || b >= 0x7f) { - sb.append('\\'); - sb.append(byteFormat.format(b)); - } - else if (b == '"' || b == '(' || b == ')' || b == '.' || - b == ';' || b == '\\' || b == '@' || b == '$') - { - sb.append('\\'); - sb.append((char)b); - } - else - sb.append((char)b); - } - return sb.toString(); -} - -/** - * Convert a Name to a String - * @param omitFinalDot If true, and the name is absolute, omit the final dot. - * @return The representation of this name as a (printable) String. - */ -public String -toString(boolean omitFinalDot) { - int labels = labels(); - if (labels == 0) - return "@"; - else if (labels == 1 && name[offset(0)] == 0) - return "."; - StringBuffer sb = new StringBuffer(); - for (int i = 0, pos = offset(0); i < labels; i++) { - int len = name[pos]; - if (len > MAXLABEL) - throw new IllegalStateException("invalid label"); - if (len == 0) { - if (!omitFinalDot) - sb.append('.'); - break; - } - if (i > 0) - sb.append('.'); - sb.append(byteString(name, pos)); - pos += (1 + len); - } - return sb.toString(); -} - -/** - * Convert a Name to a String - * @return The representation of this name as a (printable) String. - */ -public String -toString() { - return toString(false); -} - -/** - * Retrieve the nth label of a Name. This makes a copy of the label; changing - * this does not change the Name. - * @param n The label to be retrieved. The first label is 0. - */ -public byte [] -getLabel(int n) { - int pos = offset(n); - byte len = (byte)(name[pos] + 1); - byte [] label = new byte[len]; - System.arraycopy(name, pos, label, 0, len); - return label; -} - -/** - * Convert the nth label in a Name to a String - * @param n The label to be converted to a (printable) String. The first - * label is 0. - */ -public String -getLabelString(int n) { - int pos = offset(n); - return byteString(name, pos); -} - -/** - * Emit a Name in DNS wire format - * @param out The output stream containing the DNS message. - * @param c The compression context, or null of no compression is desired. - * @throws IllegalArgumentException The name is not absolute. - */ -public void -toWire(DNSOutput out, Compression c) { - if (!isAbsolute()) - throw new IllegalArgumentException("toWire() called on " + - "non-absolute name"); - - int labels = labels(); - for (int i = 0; i < labels - 1; i++) { - Name tname; - if (i == 0) - tname = this; - else - tname = new Name(this, i); - int pos = -1; - if (c != null) - pos = c.get(tname); - if (pos >= 0) { - pos |= (LABEL_MASK << 8); - out.writeU16(pos); - return; - } else { - if (c != null) - c.add(out.current(), tname); - int off = offset(i); - out.writeByteArray(name, off, name[off] + 1); - } - } - out.writeU8(0); -} - -/** - * Emit a Name in DNS wire format - * @throws IllegalArgumentException The name is not absolute. - */ -public byte [] -toWire() { - DNSOutput out = new DNSOutput(); - toWire(out, null); - return out.toByteArray(); -} - -/** - * Emit a Name in canonical DNS wire format (all lowercase) - * @param out The output stream to which the message is written. - */ -public void -toWireCanonical(DNSOutput out) { - byte [] b = toWireCanonical(); - out.writeByteArray(b); -} - -/** - * Emit a Name in canonical DNS wire format (all lowercase) - * @return The canonical form of the name. - */ -public byte [] -toWireCanonical() { - int labels = labels(); - if (labels == 0) - return (new byte[0]); - byte [] b = new byte[name.length - offset(0)]; - for (int i = 0, spos = offset(0), dpos = 0; i < labels; i++) { - int len = name[spos]; - if (len > MAXLABEL) - throw new IllegalStateException("invalid label"); - b[dpos++] = name[spos++]; - for (int j = 0; j < len; j++) - b[dpos++] = lowercase[(name[spos++] & 0xFF)]; - } - return b; -} - -/** - * Emit a Name in DNS wire format - * @param out The output stream containing the DNS message. - * @param c The compression context, or null of no compression is desired. - * @param canonical If true, emit the name in canonicalized form - * (all lowercase). - * @throws IllegalArgumentException The name is not absolute. - */ -public void -toWire(DNSOutput out, Compression c, boolean canonical) { - if (canonical) - toWireCanonical(out); - else - toWire(out, c); -} - -private final boolean -equals(byte [] b, int bpos) { - int labels = labels(); - for (int i = 0, pos = offset(0); i < labels; i++) { - if (name[pos] != b[bpos]) - return false; - int len = name[pos++]; - bpos++; - if (len > MAXLABEL) - throw new IllegalStateException("invalid label"); - for (int j = 0; j < len; j++) - if (lowercase[(name[pos++] & 0xFF)] != - lowercase[(b[bpos++] & 0xFF)]) - return false; - } - return true; -} - -/** - * Are these two Names equivalent? - */ -public boolean -equals(Object arg) { - if (arg == this) - return true; - if (arg == null || !(arg instanceof Name)) - return false; - Name d = (Name) arg; - if (d.hashcode == 0) - d.hashCode(); - if (hashcode == 0) - hashCode(); - if (d.hashcode != hashcode) - return false; - if (d.labels() != labels()) - return false; - return equals(d.name, d.offset(0)); -} - -/** - * Computes a hashcode based on the value - */ -public int -hashCode() { - if (hashcode != 0) - return (hashcode); - int code = 0; - for (int i = offset(0); i < name.length; i++) - code += ((code << 3) + lowercase[(name[i] & 0xFF)]); - hashcode = code; - return hashcode; -} - -/** - * Compares this Name to another Object. - * @param o The Object to be compared. - * @return The value 0 if the argument is a name equivalent to this name; - * a value less than 0 if the argument is less than this name in the canonical - * ordering, and a value greater than 0 if the argument is greater than this - * name in the canonical ordering. - * @throws ClassCastException if the argument is not a Name. - */ -public int -compareTo(Object o) { - Name arg = (Name) o; - - if (this == arg) - return (0); - - int labels = labels(); - int alabels = arg.labels(); - int compares = labels > alabels ? alabels : labels; - - for (int i = 1; i <= compares; i++) { - int start = offset(labels - i); - int astart = arg.offset(alabels - i); - int length = name[start]; - int alength = arg.name[astart]; - for (int j = 0; j < length && j < alength; j++) { - int n = lowercase[(name[j + start + 1]) & 0xFF] - - lowercase[(arg.name[j + astart + 1]) & 0xFF]; - if (n != 0) - return (n); - } - if (length != alength) - return (length - alength); - } - return (labels - alabels); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/NameTooLongException.java b/src/main/java/core/org/xbill/DNS/NameTooLongException.java deleted file mode 100644 index 114be39e..00000000 --- a/src/main/java/core/org/xbill/DNS/NameTooLongException.java +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2002-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * An exception thrown when a name is longer than the maximum length of a DNS - * name. - * - * @author Brian Wellington - */ - -public class NameTooLongException extends WireParseException { - -public -NameTooLongException() { - super(); -} - -public -NameTooLongException(String s) { - super(s); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/OPENPGPKEYRecord.java b/src/main/java/core/org/xbill/DNS/OPENPGPKEYRecord.java deleted file mode 100644 index 359fb676..00000000 --- a/src/main/java/core/org/xbill/DNS/OPENPGPKEYRecord.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.xbill.DNS; - -import java.io.IOException; - -import org.xbill.DNS.utils.base64; - -/** - * OPENPGPKEY Record - Stores an OpenPGP certificate associated with a name. - * RFC 7929. - * - * @author Brian Wellington - * @author Valentin Hauner - * - */ -public class OPENPGPKEYRecord extends Record { - -private static final long serialVersionUID = -1277262990243423062L; - -private byte [] cert; - -OPENPGPKEYRecord() {} - -Record -getObject() { - return new OPENPGPKEYRecord(); -} - -/** - * Creates an OPENPGPKEY Record from the given data - * - * @param cert Binary data representing the certificate - */ -public -OPENPGPKEYRecord(Name name, int dclass, long ttl, byte [] cert) -{ - super(name, Type.OPENPGPKEY, dclass, ttl); - this.cert = cert; -} - -void -rrFromWire(DNSInput in) throws IOException { - cert = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - cert = st.getBase64(); -} - -/** - * Converts rdata to a String - */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - if (cert != null) { - if (Options.check("multiline")) { - sb.append("(\n"); - sb.append(base64.formatString(cert, 64, "\t", true)); - } else { - sb.append(base64.toString(cert)); - } - } - return sb.toString(); -} - -/** - * Returns the binary representation of the certificate - */ -public byte [] -getCert() -{ - return cert; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeByteArray(cert); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/OPTRecord.java b/src/main/java/core/org/xbill/DNS/OPTRecord.java deleted file mode 100644 index cedbb396..00000000 --- a/src/main/java/core/org/xbill/DNS/OPTRecord.java +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; - -/** - * Options - describes Extended DNS (EDNS) properties of a Message. - * No specific options are defined other than those specified in the - * header. An OPT should be generated by Resolver. - * - * EDNS is a method to extend the DNS protocol while providing backwards - * compatibility and not significantly changing the protocol. This - * implementation of EDNS is mostly complete at level 0. - * - * @see Message - * @see Resolver - * - * @author Brian Wellington - */ - -public class OPTRecord extends Record { - -private static final long serialVersionUID = -6254521894809367938L; - -private List options; - -OPTRecord() {} - -Record -getObject() { - return new OPTRecord(); -} - -/** - * Creates an OPT Record. This is normally called by SimpleResolver, but can - * also be called by a server. - * @param payloadSize The size of a packet that can be reassembled on the - * sending host. - * @param xrcode The value of the extended rcode field. This is the upper - * 16 bits of the full rcode. - * @param flags Additional message flags. - * @param version The EDNS version that this DNS implementation supports. - * This should be 0 for dnsjava. - * @param options The list of options that comprise the data field. There - * are currently no defined options. - * @see ExtendedFlags - */ -public -OPTRecord(int payloadSize, int xrcode, int version, int flags, List options) { - super(Name.root, Type.OPT, payloadSize, 0); - checkU16("payloadSize", payloadSize); - checkU8("xrcode", xrcode); - checkU8("version", version); - checkU16("flags", flags); - ttl = ((long)xrcode << 24) + ((long)version << 16) + flags; - if (options != null) { - this.options = new ArrayList(options); - } -} - -/** - * Creates an OPT Record with no data. This is normally called by - * SimpleResolver, but can also be called by a server. - * @param payloadSize The size of a packet that can be reassembled on the - * sending host. - * @param xrcode The value of the extended rcode field. This is the upper - * 16 bits of the full rcode. - * @param flags Additional message flags. - * @param version The EDNS version that this DNS implementation supports. - * This should be 0 for dnsjava. - * @see ExtendedFlags - */ -public -OPTRecord(int payloadSize, int xrcode, int version, int flags) { - this(payloadSize, xrcode, version, flags, null); -} - -/** - * Creates an OPT Record with no data. This is normally called by - * SimpleResolver, but can also be called by a server. - */ -public -OPTRecord(int payloadSize, int xrcode, int version) { - this(payloadSize, xrcode, version, 0, null); -} - -void -rrFromWire(DNSInput in) throws IOException { - if (in.remaining() > 0) - options = new ArrayList(); - while (in.remaining() > 0) { - EDNSOption option = EDNSOption.fromWire(in); - options.add(option); - } -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - throw st.exception("no text format defined for OPT"); -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - if (options != null) { - sb.append(options); - sb.append(" "); - } - sb.append(" ; payload "); - sb.append(getPayloadSize()); - sb.append(", xrcode "); - sb.append(getExtendedRcode()); - sb.append(", version "); - sb.append(getVersion()); - sb.append(", flags "); - sb.append(getFlags()); - return sb.toString(); -} - -/** Returns the maximum allowed payload size. */ -public int -getPayloadSize() { - return dclass; -} - -/** - * Returns the extended Rcode - * @see Rcode - */ -public int -getExtendedRcode() { - return (int)(ttl >>> 24); -} - -/** Returns the highest supported EDNS version */ -public int -getVersion() { - return (int)((ttl >>> 16) & 0xFF); -} - -/** Returns the EDNS flags */ -public int -getFlags() { - return (int)(ttl & 0xFFFF); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - if (options == null) - return; - Iterator it = options.iterator(); - while (it.hasNext()) { - EDNSOption option = (EDNSOption) it.next(); - option.toWire(out); - } -} - -/** - * Gets all options in the OPTRecord. This returns a list of EDNSOptions. - */ -public List -getOptions() { - if (options == null) - return Collections.EMPTY_LIST; - return Collections.unmodifiableList(options); -} - -/** - * Gets all options in the OPTRecord with a specific code. This returns a list - * of EDNSOptions. - */ -public List -getOptions(int code) { - if (options == null) - return Collections.EMPTY_LIST; - List list = Collections.EMPTY_LIST; - for (Iterator it = options.iterator(); it.hasNext(); ) { - EDNSOption opt = (EDNSOption) it.next(); - if (opt.getCode() == code) { - if (list == Collections.EMPTY_LIST) - list = new ArrayList(); - list.add(opt); - } - } - return list; -} - -/** - * Determines if two OPTRecords are identical. This compares the name, type, - * class, and rdata (with names canonicalized). Additionally, because TTLs - * are relevant for OPT records, the TTLs are compared. - * @param arg The record to compare to - * @return true if the records are equal, false otherwise. - */ -public boolean -equals(final Object arg) { - return super.equals(arg) && ttl == ((OPTRecord) arg).ttl; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Opcode.java b/src/main/java/core/org/xbill/DNS/Opcode.java deleted file mode 100644 index dadbca17..00000000 --- a/src/main/java/core/org/xbill/DNS/Opcode.java +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Constants and functions relating to DNS opcodes - * - * @author Brian Wellington - */ - -public final class Opcode { - -/** A standard query */ -public static final int QUERY = 0; - -/** An inverse query (deprecated) */ -public static final int IQUERY = 1; - -/** A server status request (not used) */ -public static final int STATUS = 2; - -/** - * A message from a primary to a secondary server to initiate a zone transfer - */ -public static final int NOTIFY = 4; - -/** A dynamic update message */ -public static final int UPDATE = 5; - -private static Mnemonic opcodes = new Mnemonic("DNS Opcode", - Mnemonic.CASE_UPPER); - -static { - opcodes.setMaximum(0xF); - opcodes.setPrefix("RESERVED"); - opcodes.setNumericAllowed(true); - - opcodes.add(QUERY, "QUERY"); - opcodes.add(IQUERY, "IQUERY"); - opcodes.add(STATUS, "STATUS"); - opcodes.add(NOTIFY, "NOTIFY"); - opcodes.add(UPDATE, "UPDATE"); -} - -private -Opcode() {} - -/** Converts a numeric Opcode into a String */ -public static String -string(int i) { - return opcodes.getText(i); -} - -/** Converts a String representation of an Opcode into its numeric value */ -public static int -value(String s) { - return opcodes.getValue(s); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Options.java b/src/main/java/core/org/xbill/DNS/Options.java deleted file mode 100644 index 2f1dae34..00000000 --- a/src/main/java/core/org/xbill/DNS/Options.java +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.*; - -/** - * Boolean options:
- * bindttl - Print TTLs in BIND format
- * multiline - Print records in multiline format
- * noprintin - Don't print the class of a record if it's IN
- * verbose - Turn on general debugging statements
- * verbosemsg - Print all messages sent or received by SimpleResolver
- * verbosecompression - Print messages related to name compression
- * verbosesec - Print messages related to signature verification
- * verbosecache - Print messages related to cache lookups
- *
- * Valued options:
- * tsigfudge=n - Sets the default TSIG fudge value (in seconds)
- * sig0validity=n - Sets the default SIG(0) validity period (in seconds)
- * - * @author Brian Wellington - */ - -public final class Options { - -private static Map table; - -static { - try { - refresh(); - } - catch (SecurityException e) { - } -} - -private -Options() {} - -public static void -refresh() { - String s = System.getProperty("dnsjava.options"); - if (s != null) { - StringTokenizer st = new StringTokenizer(s, ","); - while (st.hasMoreTokens()) { - String token = st.nextToken(); - int index = token.indexOf('='); - if (index == -1) - set(token); - else { - String option = token.substring(0, index); - String value = token.substring(index + 1); - set(option, value); - } - } - } -} - -/** Clears all defined options */ -public static void -clear() { - table = null; -} - -/** Sets an option to "true" */ -public static void -set(String option) { - if (table == null) - table = new HashMap(); - table.put(option.toLowerCase(), "true"); -} - -/** Sets an option to the the supplied value */ -public static void -set(String option, String value) { - if (table == null) - table = new HashMap(); - table.put(option.toLowerCase(), value.toLowerCase()); -} - -/** Removes an option */ -public static void -unset(String option) { - if (table == null) - return; - table.remove(option.toLowerCase()); -} - -/** Checks if an option is defined */ -public static boolean -check(String option) { - if (table == null) - return false; - return (table.get(option.toLowerCase()) != null); -} - -/** Returns the value of an option */ -public static String -value(String option) { - if (table == null) - return null; - return ((String)table.get(option.toLowerCase())); -} - -/** - * Returns the value of an option as an integer, or -1 if not defined. - */ -public static int -intValue(String option) { - String s = value(option); - if (s != null) { - try { - int val = Integer.parseInt(s); - if (val > 0) - return (val); - } - catch (NumberFormatException e) { - } - } - return (-1); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/PTRRecord.java b/src/main/java/core/org/xbill/DNS/PTRRecord.java deleted file mode 100644 index 89be5781..00000000 --- a/src/main/java/core/org/xbill/DNS/PTRRecord.java +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Pointer Record - maps a domain name representing an Internet Address to - * a hostname. - * - * @author Brian Wellington - */ - -public class PTRRecord extends SingleCompressedNameBase { - -private static final long serialVersionUID = -8321636610425434192L; - -PTRRecord() {} - -Record -getObject() { - return new PTRRecord(); -} - -/** - * Creates a new PTR Record with the given data - * @param target The name of the machine with this address - */ -public -PTRRecord(Name name, int dclass, long ttl, Name target) { - super(name, Type.PTR, dclass, ttl, target, "target"); -} - -/** Gets the target of the PTR Record */ -public Name -getTarget() { - return getSingleName(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/PXRecord.java b/src/main/java/core/org/xbill/DNS/PXRecord.java deleted file mode 100644 index a4072415..00000000 --- a/src/main/java/core/org/xbill/DNS/PXRecord.java +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * X.400 mail mapping record. - * - * @author Brian Wellington - */ - -public class PXRecord extends Record { - -private static final long serialVersionUID = 1811540008806660667L; - -private int preference; -private Name map822; -private Name mapX400; - -PXRecord() {} - -Record -getObject() { - return new PXRecord(); -} - -/** - * Creates an PX Record from the given data - * @param preference The preference of this mail address. - * @param map822 The RFC 822 component of the mail address. - * @param mapX400 The X.400 component of the mail address. - */ -public -PXRecord(Name name, int dclass, long ttl, int preference, - Name map822, Name mapX400) -{ - super(name, Type.PX, dclass, ttl); - - this.preference = checkU16("preference", preference); - this.map822 = checkName("map822", map822); - this.mapX400 = checkName("mapX400", mapX400); -} - -void -rrFromWire(DNSInput in) throws IOException { - preference = in.readU16(); - map822 = new Name(in); - mapX400 = new Name(in); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - preference = st.getUInt16(); - map822 = st.getName(origin); - mapX400 = st.getName(origin); -} - -/** Converts the PX Record to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(preference); - sb.append(" "); - sb.append(map822); - sb.append(" "); - sb.append(mapX400); - return sb.toString(); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(preference); - map822.toWire(out, null, canonical); - mapX400.toWire(out, null, canonical); -} - -/** Gets the preference of the route. */ -public int -getPreference() { - return preference; -} - -/** Gets the RFC 822 component of the mail address. */ -public Name -getMap822() { - return map822; -} - -/** Gets the X.400 component of the mail address. */ -public Name -getMapX400() { - return mapX400; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/PacketLogger.java b/src/main/java/core/org/xbill/DNS/PacketLogger.java deleted file mode 100644 index 6e892934..00000000 --- a/src/main/java/core/org/xbill/DNS/PacketLogger.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.xbill.DNS; - -import java.net.*; - -/** - * Custom logger that can log all the packets that were send or received. - * @author Damian Minkov - */ -public interface PacketLogger { - public void log(String prefix, SocketAddress local, SocketAddress remote, - byte [] data); -} diff --git a/src/main/java/core/org/xbill/DNS/RPRecord.java b/src/main/java/core/org/xbill/DNS/RPRecord.java deleted file mode 100644 index 4c9017fc..00000000 --- a/src/main/java/core/org/xbill/DNS/RPRecord.java +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * Responsible Person Record - lists the mail address of a responsible person - * and a domain where TXT records are available. - * - * @author Tom Scola (tscola@research.att.com) - * @author Brian Wellington - */ - -public class RPRecord extends Record { - -private static final long serialVersionUID = 8124584364211337460L; - -private Name mailbox; -private Name textDomain; - -RPRecord() {} - -Record -getObject() { - return new RPRecord(); -} - -/** - * Creates an RP Record from the given data - * @param mailbox The responsible person - * @param textDomain The address where TXT records can be found - */ -public -RPRecord(Name name, int dclass, long ttl, Name mailbox, Name textDomain) { - super(name, Type.RP, dclass, ttl); - - this.mailbox = checkName("mailbox", mailbox); - this.textDomain = checkName("textDomain", textDomain); -} - -void -rrFromWire(DNSInput in) throws IOException { - mailbox = new Name(in); - textDomain = new Name(in); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - mailbox = st.getName(origin); - textDomain = st.getName(origin); -} - -/** Converts the RP Record to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(mailbox); - sb.append(" "); - sb.append(textDomain); - return sb.toString(); -} - -/** Gets the mailbox address of the RP Record */ -public Name -getMailbox() { - return mailbox; -} - -/** Gets the text domain info of the RP Record */ -public Name -getTextDomain() { - return textDomain; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - mailbox.toWire(out, null, canonical); - textDomain.toWire(out, null, canonical); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/RRSIGRecord.java b/src/main/java/core/org/xbill/DNS/RRSIGRecord.java deleted file mode 100644 index c0928395..00000000 --- a/src/main/java/core/org/xbill/DNS/RRSIGRecord.java +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.*; - -/** - * Recource Record Signature - An RRSIG provides the digital signature of an - * RRset, so that the data can be authenticated by a DNSSEC-capable resolver. - * The signature is generated by a key contained in a DNSKEY Record. - * @see RRset - * @see DNSSEC - * @see KEYRecord - * - * @author Brian Wellington - */ - -public class RRSIGRecord extends SIGBase { - -private static final long serialVersionUID = -2609150673537226317L; - -RRSIGRecord() {} - -Record -getObject() { - return new RRSIGRecord(); -} - -/** - * Creates an RRSIG Record from the given data - * @param covered The RRset type covered by this signature - * @param alg The cryptographic algorithm of the key that generated the - * signature - * @param origttl The original TTL of the RRset - * @param expire The time at which the signature expires - * @param timeSigned The time at which this signature was generated - * @param footprint The footprint/key id of the signing key. - * @param signer The owner of the signing key - * @param signature Binary data representing the signature - */ -public -RRSIGRecord(Name name, int dclass, long ttl, int covered, int alg, long origttl, - Date expire, Date timeSigned, int footprint, Name signer, - byte [] signature) -{ - super(name, Type.RRSIG, dclass, ttl, covered, alg, origttl, expire, - timeSigned, footprint, signer, signature); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/RRset.java b/src/main/java/core/org/xbill/DNS/RRset.java deleted file mode 100644 index bcc388a0..00000000 --- a/src/main/java/core/org/xbill/DNS/RRset.java +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.Serializable; -import java.util.*; - -/** - * A set of Records with the same name, type, and class. Also included - * are all RRSIG records signing the data records. - * @see Record - * @see RRSIGRecord - * - * @author Brian Wellington - */ - -public class RRset implements Serializable { - -private static final long serialVersionUID = -3270249290171239695L; - -/* - * rrs contains both normal and RRSIG records, with the RRSIG records - * at the end. - */ -private List rrs; -private short nsigs; -private short position; - -/** Creates an empty RRset */ -public -RRset() { - rrs = new ArrayList(1); - nsigs = 0; - position = 0; -} - -/** Creates an RRset and sets its contents to the specified record */ -public -RRset(Record record) { - this(); - safeAddRR(record); -} - -/** Creates an RRset with the contents of an existing RRset */ -public -RRset(RRset rrset) { - synchronized (rrset) { - rrs = (List) ((ArrayList)rrset.rrs).clone(); - nsigs = rrset.nsigs; - position = rrset.position; - } -} - -private void -safeAddRR(Record r) { - if (!(r instanceof RRSIGRecord)) { - if (nsigs == 0) - rrs.add(r); - else - rrs.add(rrs.size() - nsigs, r); - } else { - rrs.add(r); - nsigs++; - } -} - -/** Adds a Record to an RRset */ -public synchronized void -addRR(Record r) { - if (rrs.size() == 0) { - safeAddRR(r); - return; - } - Record first = first(); - if (!r.sameRRset(first)) - throw new IllegalArgumentException("record does not match " + - "rrset"); - - if (r.getTTL() != first.getTTL()) { - if (r.getTTL() > first.getTTL()) { - r = r.cloneRecord(); - r.setTTL(first.getTTL()); - } else { - for (int i = 0; i < rrs.size(); i++) { - Record tmp = (Record) rrs.get(i); - tmp = tmp.cloneRecord(); - tmp.setTTL(r.getTTL()); - rrs.set(i, tmp); - } - } - } - - if (!rrs.contains(r)) - safeAddRR(r); -} - -/** Deletes a Record from an RRset */ -public synchronized void -deleteRR(Record r) { - if (rrs.remove(r) && (r instanceof RRSIGRecord)) - nsigs--; -} - -/** Deletes all Records from an RRset */ -public synchronized void -clear() { - rrs.clear(); - position = 0; - nsigs = 0; -} - -private synchronized Iterator -iterator(boolean data, boolean cycle) { - int size, start, total; - - total = rrs.size(); - - if (data) - size = total - nsigs; - else - size = nsigs; - if (size == 0) - return Collections.EMPTY_LIST.iterator(); - - if (data) { - if (!cycle) - start = 0; - else { - if (position >= size) - position = 0; - start = position++; - } - } else { - start = total - nsigs; - } - - List list = new ArrayList(size); - if (data) { - list.addAll(rrs.subList(start, size)); - if (start != 0) - list.addAll(rrs.subList(0, start)); - } else { - list.addAll(rrs.subList(start, total)); - } - - return list.iterator(); -} - -/** - * Returns an Iterator listing all (data) records. - * @param cycle If true, cycle through the records so that each Iterator will - * start with a different record. - */ -public synchronized Iterator -rrs(boolean cycle) { - return iterator(true, cycle); -} - -/** - * Returns an Iterator listing all (data) records. This cycles through - * the records, so each Iterator will start with a different record. - */ -public synchronized Iterator -rrs() { - return iterator(true, true); -} - -/** Returns an Iterator listing all signature records */ -public synchronized Iterator -sigs() { - return iterator(false, false); -} - -/** Returns the number of (data) records */ -public synchronized int -size() { - return rrs.size() - nsigs; -} - -/** - * Returns the name of the records - * @see Name - */ -public Name -getName() { - return first().getName(); -} - -/** - * Returns the type of the records - * @see Type - */ -public int -getType() { - return first().getRRsetType(); -} - -/** - * Returns the class of the records - * @see DClass - */ -public int -getDClass() { - return first().getDClass(); -} - -/** Returns the ttl of the records */ -public synchronized long -getTTL() { - return first().getTTL(); -} - -/** - * Returns the first record - * @throws IllegalStateException if the rrset is empty - */ -public synchronized Record -first() { - if (rrs.size() == 0) - throw new IllegalStateException("rrset is empty"); - return (Record) rrs.get(0); -} - -private String -iteratorToString(Iterator it) { - StringBuffer sb = new StringBuffer(); - while (it.hasNext()) { - Record rr = (Record) it.next(); - sb.append("["); - sb.append(rr.rdataToString()); - sb.append("]"); - if (it.hasNext()) - sb.append(" "); - } - return sb.toString(); -} - -/** Converts the RRset to a String */ -public String -toString() { - if (rrs.size() == 0) - return ("{empty}"); - StringBuffer sb = new StringBuffer(); - sb.append("{ "); - sb.append(getName() + " "); - sb.append(getTTL() + " "); - sb.append(DClass.string(getDClass()) + " "); - sb.append(Type.string(getType()) + " "); - sb.append(iteratorToString(iterator(true, false))); - if (nsigs > 0) { - sb.append(" sigs: "); - sb.append(iteratorToString(iterator(false, false))); - } - sb.append(" }"); - return sb.toString(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/RTRecord.java b/src/main/java/core/org/xbill/DNS/RTRecord.java deleted file mode 100644 index 549731ec..00000000 --- a/src/main/java/core/org/xbill/DNS/RTRecord.java +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Route Through Record - lists a route preference and intermediate host. - * - * @author Brian Wellington - */ - -public class RTRecord extends U16NameBase { - -private static final long serialVersionUID = -3206215651648278098L; - -RTRecord() {} - -Record -getObject() { - return new RTRecord(); -} - -/** - * Creates an RT Record from the given data - * @param preference The preference of the route. Smaller numbers indicate - * more preferred routes. - * @param intermediateHost The domain name of the host to use as a router. - */ -public -RTRecord(Name name, int dclass, long ttl, int preference, - Name intermediateHost) -{ - super(name, Type.RT, dclass, ttl, preference, "preference", - intermediateHost, "intermediateHost"); -} - -/** Gets the preference of the route. */ -public int -getPreference() { - return getU16Field(); -} - -/** Gets the host to use as a router. */ -public Name -getIntermediateHost() { - return getNameField(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Rcode.java b/src/main/java/core/org/xbill/DNS/Rcode.java deleted file mode 100644 index 7f0dd1f1..00000000 --- a/src/main/java/core/org/xbill/DNS/Rcode.java +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Constants and functions relating to DNS rcodes (error values) - * - * @author Brian Wellington - */ - -public final class Rcode { - -private static Mnemonic rcodes = new Mnemonic("DNS Rcode", - Mnemonic.CASE_UPPER); - -private static Mnemonic tsigrcodes = new Mnemonic("TSIG rcode", - Mnemonic.CASE_UPPER); - -/** No error */ -public static final int NOERROR = 0; - -/** Format error */ -public static final int FORMERR = 1; - -/** Server failure */ -public static final int SERVFAIL = 2; - -/** The name does not exist */ -public static final int NXDOMAIN = 3; - -/** The operation requested is not implemented */ -public static final int NOTIMP = 4; - -/** Deprecated synonym for NOTIMP. */ -public static final int NOTIMPL = 4; - -/** The operation was refused by the server */ -public static final int REFUSED = 5; - -/** The name exists */ -public static final int YXDOMAIN = 6; - -/** The RRset (name, type) exists */ -public static final int YXRRSET = 7; - -/** The RRset (name, type) does not exist */ -public static final int NXRRSET = 8; - -/** The requestor is not authorized to perform this operation */ -public static final int NOTAUTH = 9; - -/** The zone specified is not a zone */ -public static final int NOTZONE = 10; - -/* EDNS extended rcodes */ -/** Unsupported EDNS level */ -public static final int BADVERS = 16; - -/* TSIG/TKEY only rcodes */ -/** The signature is invalid (TSIG/TKEY extended error) */ -public static final int BADSIG = 16; - -/** The key is invalid (TSIG/TKEY extended error) */ -public static final int BADKEY = 17; - -/** The time is out of range (TSIG/TKEY extended error) */ -public static final int BADTIME = 18; - -/** The mode is invalid (TKEY extended error) */ -public static final int BADMODE = 19; - -static { - rcodes.setMaximum(0xFFF); - rcodes.setPrefix("RESERVED"); - rcodes.setNumericAllowed(true); - - rcodes.add(NOERROR, "NOERROR"); - rcodes.add(FORMERR, "FORMERR"); - rcodes.add(SERVFAIL, "SERVFAIL"); - rcodes.add(NXDOMAIN, "NXDOMAIN"); - rcodes.add(NOTIMP, "NOTIMP"); - rcodes.addAlias(NOTIMP, "NOTIMPL"); - rcodes.add(REFUSED, "REFUSED"); - rcodes.add(YXDOMAIN, "YXDOMAIN"); - rcodes.add(YXRRSET, "YXRRSET"); - rcodes.add(NXRRSET, "NXRRSET"); - rcodes.add(NOTAUTH, "NOTAUTH"); - rcodes.add(NOTZONE, "NOTZONE"); - rcodes.add(BADVERS, "BADVERS"); - - tsigrcodes.setMaximum(0xFFFF); - tsigrcodes.setPrefix("RESERVED"); - tsigrcodes.setNumericAllowed(true); - tsigrcodes.addAll(rcodes); - - tsigrcodes.add(BADSIG, "BADSIG"); - tsigrcodes.add(BADKEY, "BADKEY"); - tsigrcodes.add(BADTIME, "BADTIME"); - tsigrcodes.add(BADMODE, "BADMODE"); -} - -private -Rcode() {} - -/** Converts a numeric Rcode into a String */ -public static String -string(int i) { - return rcodes.getText(i); -} - -/** Converts a numeric TSIG extended Rcode into a String */ -public static String -TSIGstring(int i) { - return tsigrcodes.getText(i); -} - -/** Converts a String representation of an Rcode into its numeric value */ -public static int -value(String s) { - return rcodes.getValue(s); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Record.java b/src/main/java/core/org/xbill/DNS/Record.java deleted file mode 100644 index 8da70159..00000000 --- a/src/main/java/core/org/xbill/DNS/Record.java +++ /dev/null @@ -1,736 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.text.*; -import java.util.*; -import org.xbill.DNS.utils.*; - -/** - * A generic DNS resource record. The specific record types extend this class. - * A record contains a name, type, class, ttl, and rdata. - * - * @author Brian Wellington - */ - -public abstract class Record implements Cloneable, Comparable, Serializable { - -private static final long serialVersionUID = 2694906050116005466L; - -protected Name name; -protected int type, dclass; -protected long ttl; - -private static final DecimalFormat byteFormat = new DecimalFormat(); - -static { - byteFormat.setMinimumIntegerDigits(3); -} - -protected -Record() {} - -Record(Name name, int type, int dclass, long ttl) { - if (!name.isAbsolute()) - throw new RelativeNameException(name); - Type.check(type); - DClass.check(dclass); - TTL.check(ttl); - this.name = name; - this.type = type; - this.dclass = dclass; - this.ttl = ttl; -} - -/** - * Creates an empty record of the correct type; must be overriden - */ -abstract Record -getObject(); - -private static final Record -getEmptyRecord(Name name, int type, int dclass, long ttl, boolean hasData) { - Record proto, rec; - - if (hasData) { - proto = Type.getProto(type); - if (proto != null) - rec = proto.getObject(); - else - rec = new UNKRecord(); - } else - rec = new EmptyRecord(); - rec.name = name; - rec.type = type; - rec.dclass = dclass; - rec.ttl = ttl; - return rec; -} - -/** - * Converts the type-specific RR to wire format - must be overriden - */ -abstract void -rrFromWire(DNSInput in) throws IOException; - -private static Record -newRecord(Name name, int type, int dclass, long ttl, int length, DNSInput in) -throws IOException -{ - Record rec; - rec = getEmptyRecord(name, type, dclass, ttl, in != null); - if (in != null) { - if (in.remaining() < length) - throw new WireParseException("truncated record"); - in.setActive(length); - - rec.rrFromWire(in); - - if (in.remaining() > 0) - throw new WireParseException("invalid record length"); - in.clearActive(); - } - return rec; -} - -/** - * Creates a new record, with the given parameters. - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * @param ttl The record's time to live. - * @param length The length of the record's data. - * @param data The rdata of the record, in uncompressed DNS wire format. Only - * the first length bytes are used. - */ -public static Record -newRecord(Name name, int type, int dclass, long ttl, int length, byte [] data) { - if (!name.isAbsolute()) - throw new RelativeNameException(name); - Type.check(type); - DClass.check(dclass); - TTL.check(ttl); - - DNSInput in; - if (data != null) - in = new DNSInput(data); - else - in = null; - try { - return newRecord(name, type, dclass, ttl, length, in); - } - catch (IOException e) { - return null; - } -} - -/** - * Creates a new record, with the given parameters. - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * @param ttl The record's time to live. - * @param data The complete rdata of the record, in uncompressed DNS wire - * format. - */ -public static Record -newRecord(Name name, int type, int dclass, long ttl, byte [] data) { - return newRecord(name, type, dclass, ttl, data.length, data); -} - -/** - * Creates a new empty record, with the given parameters. - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * @param ttl The record's time to live. - * @return An object of a subclass of Record - */ -public static Record -newRecord(Name name, int type, int dclass, long ttl) { - if (!name.isAbsolute()) - throw new RelativeNameException(name); - Type.check(type); - DClass.check(dclass); - TTL.check(ttl); - - return getEmptyRecord(name, type, dclass, ttl, false); -} - -/** - * Creates a new empty record, with the given parameters. This method is - * designed to create records that will be added to the QUERY section - * of a message. - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * @return An object of a subclass of Record - */ -public static Record -newRecord(Name name, int type, int dclass) { - return newRecord(name, type, dclass, 0); -} - -static Record -fromWire(DNSInput in, int section, boolean isUpdate) throws IOException { - int type, dclass; - long ttl; - int length; - Name name; - Record rec; - - name = new Name(in); - type = in.readU16(); - dclass = in.readU16(); - - if (section == Section.QUESTION) - return newRecord(name, type, dclass); - - ttl = in.readU32(); - length = in.readU16(); - if (length == 0 && isUpdate && - (section == Section.PREREQ || section == Section.UPDATE)) - return newRecord(name, type, dclass, ttl); - rec = newRecord(name, type, dclass, ttl, length, in); - return rec; -} - -static Record -fromWire(DNSInput in, int section) throws IOException { - return fromWire(in, section, false); -} - -/** - * Builds a Record from DNS uncompressed wire format. - */ -public static Record -fromWire(byte [] b, int section) throws IOException { - return fromWire(new DNSInput(b), section, false); -} - -void -toWire(DNSOutput out, int section, Compression c) { - name.toWire(out, c); - out.writeU16(type); - out.writeU16(dclass); - if (section == Section.QUESTION) - return; - out.writeU32(ttl); - int lengthPosition = out.current(); - out.writeU16(0); /* until we know better */ - rrToWire(out, c, false); - int rrlength = out.current() - lengthPosition - 2; - out.writeU16At(rrlength, lengthPosition); -} - -/** - * Converts a Record into DNS uncompressed wire format. - */ -public byte [] -toWire(int section) { - DNSOutput out = new DNSOutput(); - toWire(out, section, null); - return out.toByteArray(); -} - -private void -toWireCanonical(DNSOutput out, boolean noTTL) { - name.toWireCanonical(out); - out.writeU16(type); - out.writeU16(dclass); - if (noTTL) { - out.writeU32(0); - } else { - out.writeU32(ttl); - } - int lengthPosition = out.current(); - out.writeU16(0); /* until we know better */ - rrToWire(out, null, true); - int rrlength = out.current() - lengthPosition - 2; - out.writeU16At(rrlength, lengthPosition); -} - -/* - * Converts a Record into canonical DNS uncompressed wire format (all names are - * converted to lowercase), optionally ignoring the TTL. - */ -private byte [] -toWireCanonical(boolean noTTL) { - DNSOutput out = new DNSOutput(); - toWireCanonical(out, noTTL); - return out.toByteArray(); -} - -/** - * Converts a Record into canonical DNS uncompressed wire format (all names are - * converted to lowercase). - */ -public byte [] -toWireCanonical() { - return toWireCanonical(false); -} - -/** - * Converts the rdata in a Record into canonical DNS uncompressed wire format - * (all names are converted to lowercase). - */ -public byte [] -rdataToWireCanonical() { - DNSOutput out = new DNSOutput(); - rrToWire(out, null, true); - return out.toByteArray(); -} - -/** - * Converts the type-specific RR to text format - must be overriden - */ -abstract String rrToString(); - -/** - * Converts the rdata portion of a Record into a String representation - */ -public String -rdataToString() { - return rrToString(); -} - -/** - * Converts a Record into a String representation - */ -public String -toString() { - StringBuffer sb = new StringBuffer(); - sb.append(name); - if (sb.length() < 8) - sb.append("\t"); - if (sb.length() < 16) - sb.append("\t"); - sb.append("\t"); - if (Options.check("BINDTTL")) - sb.append(TTL.format(ttl)); - else - sb.append(ttl); - sb.append("\t"); - if (dclass != DClass.IN || !Options.check("noPrintIN")) { - sb.append(DClass.string(dclass)); - sb.append("\t"); - } - sb.append(Type.string(type)); - String rdata = rrToString(); - if (!rdata.equals("")) { - sb.append("\t"); - sb.append(rdata); - } - return sb.toString(); -} - -/** - * Converts the text format of an RR to the internal format - must be overriden - */ -abstract void -rdataFromString(Tokenizer st, Name origin) throws IOException; - -/** - * Converts a String into a byte array. - */ -protected static byte [] -byteArrayFromString(String s) throws TextParseException { - byte [] array = s.getBytes(); - boolean escaped = false; - boolean hasEscapes = false; - - for (int i = 0; i < array.length; i++) { - if (array[i] == '\\') { - hasEscapes = true; - break; - } - } - if (!hasEscapes) { - if (array.length > 255) { - throw new TextParseException("text string too long"); - } - return array; - } - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - int digits = 0; - int intval = 0; - for (int i = 0; i < array.length; i++) { - byte b = array[i]; - if (escaped) { - if (b >= '0' && b <= '9' && digits < 3) { - digits++; - intval *= 10; - intval += (b - '0'); - if (intval > 255) - throw new TextParseException - ("bad escape"); - if (digits < 3) - continue; - b = (byte) intval; - } - else if (digits > 0 && digits < 3) - throw new TextParseException("bad escape"); - os.write(b); - escaped = false; - } - else if (array[i] == '\\') { - escaped = true; - digits = 0; - intval = 0; - } - else - os.write(array[i]); - } - if (digits > 0 && digits < 3) - throw new TextParseException("bad escape"); - array = os.toByteArray(); - if (array.length > 255) { - throw new TextParseException("text string too long"); - } - - return os.toByteArray(); -} - -/** - * Converts a byte array into a String. - */ -protected static String -byteArrayToString(byte [] array, boolean quote) { - StringBuffer sb = new StringBuffer(); - if (quote) - sb.append('"'); - for (int i = 0; i < array.length; i++) { - int b = array[i] & 0xFF; - if (b < 0x20 || b >= 0x7f) { - sb.append('\\'); - sb.append(byteFormat.format(b)); - } else if (b == '"' || b == '\\') { - sb.append('\\'); - sb.append((char)b); - } else - sb.append((char)b); - } - if (quote) - sb.append('"'); - return sb.toString(); -} - -/** - * Converts a byte array into the unknown RR format. - */ -protected static String -unknownToString(byte [] data) { - StringBuffer sb = new StringBuffer(); - sb.append("\\# "); - sb.append(data.length); - sb.append(" "); - sb.append(base16.toString(data)); - return sb.toString(); -} - -/** - * Builds a new Record from its textual representation - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * @param ttl The record's time to live. - * @param st A tokenizer containing the textual representation of the rdata. - * @param origin The default origin to be appended to relative domain names. - * @return The new record - * @throws IOException The text format was invalid. - */ -public static Record -fromString(Name name, int type, int dclass, long ttl, Tokenizer st, Name origin) -throws IOException -{ - Record rec; - - if (!name.isAbsolute()) - throw new RelativeNameException(name); - Type.check(type); - DClass.check(dclass); - TTL.check(ttl); - - Tokenizer.Token t = st.get(); - if (t.type == Tokenizer.IDENTIFIER && t.value.equals("\\#")) { - int length = st.getUInt16(); - byte [] data = st.getHex(); - if (data == null) { - data = new byte[0]; - } - if (length != data.length) - throw st.exception("invalid unknown RR encoding: " + - "length mismatch"); - DNSInput in = new DNSInput(data); - return newRecord(name, type, dclass, ttl, length, in); - } - st.unget(); - rec = getEmptyRecord(name, type, dclass, ttl, true); - rec.rdataFromString(st, origin); - t = st.get(); - if (t.type != Tokenizer.EOL && t.type != Tokenizer.EOF) { - throw st.exception("unexpected tokens at end of record"); - } - return rec; -} - -/** - * Builds a new Record from its textual representation - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * @param ttl The record's time to live. - * @param s The textual representation of the rdata. - * @param origin The default origin to be appended to relative domain names. - * @return The new record - * @throws IOException The text format was invalid. - */ -public static Record -fromString(Name name, int type, int dclass, long ttl, String s, Name origin) -throws IOException -{ - return fromString(name, type, dclass, ttl, new Tokenizer(s), origin); -} - -/** - * Returns the record's name - * @see Name - */ -public Name -getName() { - return name; -} - -/** - * Returns the record's type - * @see Type - */ -public int -getType() { - return type; -} - -/** - * Returns the type of RRset that this record would belong to. For all types - * except RRSIG, this is equivalent to getType(). - * @return The type of record, if not RRSIG. If the type is RRSIG, - * the type covered is returned. - * @see Type - * @see RRset - * @see SIGRecord - */ -public int -getRRsetType() { - if (type == Type.RRSIG) { - RRSIGRecord sig = (RRSIGRecord) this; - return sig.getTypeCovered(); - } - return type; -} - -/** - * Returns the record's class - */ -public int -getDClass() { - return dclass; -} - -/** - * Returns the record's TTL - */ -public long -getTTL() { - return ttl; -} - -/** - * Converts the type-specific RR to wire format - must be overriden - */ -abstract void -rrToWire(DNSOutput out, Compression c, boolean canonical); - -/** - * Determines if two Records could be part of the same RRset. - * This compares the name, type, and class of the Records; the ttl and - * rdata are not compared. - */ -public boolean -sameRRset(Record rec) { - return (getRRsetType() == rec.getRRsetType() && - dclass == rec.dclass && - name.equals(rec.name)); -} - -/** - * Determines if two Records are identical. This compares the name, type, - * class, and rdata (with names canonicalized). The TTLs are not compared. - * @param arg The record to compare to - * @return true if the records are equal, false otherwise. - */ -public boolean -equals(Object arg) { - if (arg == null || !(arg instanceof Record)) - return false; - Record r = (Record) arg; - if (type != r.type || dclass != r.dclass || !name.equals(r.name)) - return false; - byte [] array1 = rdataToWireCanonical(); - byte [] array2 = r.rdataToWireCanonical(); - return Arrays.equals(array1, array2); -} - -/** - * Generates a hash code based on the Record's data. - */ -public int -hashCode() { - byte [] array = toWireCanonical(true); - int code = 0; - for (int i = 0; i < array.length; i++) - code += ((code << 3) + (array[i] & 0xFF)); - return code; -} - -Record -cloneRecord() { - try { - return (Record) clone(); - } - catch (CloneNotSupportedException e) { - throw new IllegalStateException(); - } -} - -/** - * Creates a new record identical to the current record, but with a different - * name. This is most useful for replacing the name of a wildcard record. - */ -public Record -withName(Name name) { - if (!name.isAbsolute()) - throw new RelativeNameException(name); - Record rec = cloneRecord(); - rec.name = name; - return rec; -} - -/** - * Creates a new record identical to the current record, but with a different - * class and ttl. This is most useful for dynamic update. - */ -Record -withDClass(int dclass, long ttl) { - Record rec = cloneRecord(); - rec.dclass = dclass; - rec.ttl = ttl; - return rec; -} - -/* Sets the TTL to the specified value. This is intentionally not public. */ -void -setTTL(long ttl) { - this.ttl = ttl; -} - -/** - * Compares this Record to another Object. - * @param o The Object to be compared. - * @return The value 0 if the argument is a record equivalent to this record; - * a value less than 0 if the argument is less than this record in the - * canonical ordering, and a value greater than 0 if the argument is greater - * than this record in the canonical ordering. The canonical ordering - * is defined to compare by name, class, type, and rdata. - * @throws ClassCastException if the argument is not a Record. - */ -public int -compareTo(Object o) { - Record arg = (Record) o; - - if (this == arg) - return (0); - - int n = name.compareTo(arg.name); - if (n != 0) - return (n); - n = dclass - arg.dclass; - if (n != 0) - return (n); - n = type - arg.type; - if (n != 0) - return (n); - byte [] rdata1 = rdataToWireCanonical(); - byte [] rdata2 = arg.rdataToWireCanonical(); - for (int i = 0; i < rdata1.length && i < rdata2.length; i++) { - n = (rdata1[i] & 0xFF) - (rdata2[i] & 0xFF); - if (n != 0) - return (n); - } - return (rdata1.length - rdata2.length); -} - -/** - * Returns the name for which additional data processing should be done - * for this record. This can be used both for building responses and - * parsing responses. - * @return The name to used for additional data processing, or null if this - * record type does not require additional data processing. - */ -public Name -getAdditionalName() { - return null; -} - -/* Checks that an int contains an unsigned 8 bit value */ -static int -checkU8(String field, int val) { - if (val < 0 || val > 0xFF) - throw new IllegalArgumentException("\"" + field + "\" " + val + - " must be an unsigned 8 " + - "bit value"); - return val; -} - -/* Checks that an int contains an unsigned 16 bit value */ -static int -checkU16(String field, int val) { - if (val < 0 || val > 0xFFFF) - throw new IllegalArgumentException("\"" + field + "\" " + val + - " must be an unsigned 16 " + - "bit value"); - return val; -} - -/* Checks that a long contains an unsigned 32 bit value */ -static long -checkU32(String field, long val) { - if (val < 0 || val > 0xFFFFFFFFL) - throw new IllegalArgumentException("\"" + field + "\" " + val + - " must be an unsigned 32 " + - "bit value"); - return val; -} - -/* Checks that a name is absolute */ -static Name -checkName(String field, Name name) { - if (!name.isAbsolute()) - throw new RelativeNameException(name); - return name; -} - -static byte [] -checkByteArrayLength(String field, byte [] array, int maxLength) { - if (array.length > 0xFFFF) - throw new IllegalArgumentException("\"" + field + "\" array " + - "must have no more than " + - maxLength + " elements"); - byte [] out = new byte[array.length]; - System.arraycopy(array, 0, out, 0, array.length); - return out; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/RelativeNameException.java b/src/main/java/core/org/xbill/DNS/RelativeNameException.java deleted file mode 100644 index 869fd39b..00000000 --- a/src/main/java/core/org/xbill/DNS/RelativeNameException.java +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * An exception thrown when a relative name is passed as an argument to - * a method requiring an absolute name. - * - * @author Brian Wellington - */ - -public class RelativeNameException extends IllegalArgumentException { - -public -RelativeNameException(Name name) { - super("'" + name + "' is not an absolute name"); -} - -public -RelativeNameException(String s) { - super(s); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/ResolveThread.java b/src/main/java/core/org/xbill/DNS/ResolveThread.java deleted file mode 100644 index 3087cdbf..00000000 --- a/src/main/java/core/org/xbill/DNS/ResolveThread.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * A special-purpose thread used by Resolvers (both SimpleResolver and - * ExtendedResolver) to perform asynchronous queries. - * - * @author Brian Wellington - */ - -class ResolveThread extends Thread { - -private Message query; -private Object id; -private ResolverListener listener; -private Resolver res; - -/** Creates a new ResolveThread */ -public -ResolveThread(Resolver res, Message query, Object id, - ResolverListener listener) -{ - this.res = res; - this.query = query; - this.id = id; - this.listener = listener; -} - - -/** - * Performs the query, and executes the callback. - */ -public void -run() { - try { - Message response = res.send(query); - listener.receiveMessage(id, response); - } - catch (Exception e) { - listener.handleException(id, e); - } -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Resolver.java b/src/main/java/core/org/xbill/DNS/Resolver.java deleted file mode 100644 index 7d28d408..00000000 --- a/src/main/java/core/org/xbill/DNS/Resolver.java +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; - -/** - * Interface describing a resolver. - * - * @author Brian Wellington - */ - -public interface Resolver { - -/** - * Sets the port to communicate with on the server - * @param port The port to send messages to - */ -void setPort(int port); - -/** - * Sets whether TCP connections will be sent by default - * @param flag Indicates whether TCP connections are made - */ -void setTCP(boolean flag); - -/** - * Sets whether truncated responses will be ignored. If not, a truncated - * response over UDP will cause a retransmission over TCP. - * @param flag Indicates whether truncated responses should be ignored. - */ -void setIgnoreTruncation(boolean flag); - -/** - * Sets the EDNS version used on outgoing messages. - * @param level The EDNS level to use. 0 indicates EDNS0 and -1 indicates no - * EDNS. - * @throws IllegalArgumentException An invalid level was indicated. - */ -void setEDNS(int level); - -/** - * Sets the EDNS information on outgoing messages. - * @param level The EDNS level to use. 0 indicates EDNS0 and -1 indicates no - * EDNS. - * @param payloadSize The maximum DNS packet size that this host is capable - * of receiving over UDP. If 0 is specified, the default (1280) is used. - * @param flags EDNS extended flags to be set in the OPT record. - * @param options EDNS options to be set in the OPT record, specified as a - * List of OPTRecord.Option elements. - * @throws IllegalArgumentException An invalid field was specified. - * @see OPTRecord - */ -void setEDNS(int level, int payloadSize, int flags, List options); - -/** - * Specifies the TSIG key that messages will be signed with - * @param key The key - */ -void setTSIGKey(TSIG key); - -/** - * Sets the amount of time to wait for a response before giving up. - * @param secs The number of seconds to wait. - * @param msecs The number of milliseconds to wait. - */ -void setTimeout(int secs, int msecs); - -/** - * Sets the amount of time to wait for a response before giving up. - * @param secs The number of seconds to wait. - */ -void setTimeout(int secs); - -/** - * Sends a message and waits for a response. - * @param query The query to send. - * @return The response - * @throws IOException An error occurred while sending or receiving. - */ -Message send(Message query) throws IOException; - -/** - * Asynchronously sends a message registering a listener to receive a callback - * on success or exception. Multiple asynchronous lookups can be performed - * in parallel. Since the callback may be invoked before the function returns, - * external synchronization is necessary. - * @param query The query to send - * @param listener The object containing the callbacks. - * @return An identifier, which is also a parameter in the callback - */ -Object sendAsync(final Message query, final ResolverListener listener); - -} diff --git a/src/main/java/core/org/xbill/DNS/ResolverConfig.java b/src/main/java/core/org/xbill/DNS/ResolverConfig.java deleted file mode 100644 index d003d67f..00000000 --- a/src/main/java/core/org/xbill/DNS/ResolverConfig.java +++ /dev/null @@ -1,511 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; - -/** - * A class that tries to locate name servers and the search path to - * be appended to unqualified names. - * - * The following are attempted, in order, until one succeeds. - * - * - * These routines will be called internally when creating Resolvers/Lookups - * without explicitly specifying server names, and can also be called - * directly if desired. - * - * @author Brian Wellington - * @author Yannick Meudal - * @author Arnt Gulbrandsen - */ - -public class ResolverConfig { - -private String [] servers = null; -private Name [] searchlist = null; -private int ndots = -1; - -private static ResolverConfig currentConfig; - -static { - refresh(); -} - -public -ResolverConfig() { - if (findProperty()) - return; - //if (findSunJVM()) - // return; - if (servers == null || searchlist == null) { - String OS = System.getProperty("os.name"); - String vendor = System.getProperty("java.vendor"); - if (OS.indexOf("Windows") != -1) { - if (OS.indexOf("95") != -1 || - OS.indexOf("98") != -1 || - OS.indexOf("ME") != -1) - find95(); - else - findNT(); - } else if (OS.indexOf("NetWare") != -1) { - findNetware(); - } else if (vendor.indexOf("Android") != -1) { - findAndroid(); - } else { - findUnix(); - } - } -} - -private void -addServer(String server, List list) { - if (list.contains(server)) - return; - if (Options.check("verbose")) - System.out.println("adding server " + server); - list.add(server); -} - -private void -addSearch(String search, List list) { - Name name; - if (Options.check("verbose")) - System.out.println("adding search " + search); - try { - name = Name.fromString(search, Name.root); - } - catch (TextParseException e) { - return; - } - if (list.contains(name)) - return; - list.add(name); -} - -private int -parseNdots(String token) { - token = token.substring(6); - try { - int ndots = Integer.parseInt(token); - if (ndots >= 0) { - if (Options.check("verbose")) - System.out.println("setting ndots " + token); - return ndots; - } - } - catch (NumberFormatException e) { - } - return -1; -} - -private void -configureFromLists(List lserver, List lsearch) { - if (servers == null && lserver.size() > 0) - servers = (String []) lserver.toArray(new String[0]); - if (searchlist == null && lsearch.size() > 0) - searchlist = (Name []) lsearch.toArray(new Name[0]); -} - -private void -configureNdots(int lndots) { - if (ndots < 0 && lndots > 0) - ndots = lndots; -} - -/** - * Looks in the system properties to find servers and a search path. - * Servers are defined by dns.server=server1,server2... - * The search path is defined by dns.search=domain1,domain2... - */ -private boolean -findProperty() { - String prop; - List lserver = new ArrayList(0); - List lsearch = new ArrayList(0); - - // add dns server in Google - addServer("8.8.8.8", lserver); - //StringTokenizer st; - - //prop = System.getProperty("dns.server"); - //if (prop != null) { - // st = new StringTokenizer(prop, ","); - // while (st.hasMoreTokens()) - // addServer(st.nextToken(), lserver); - //} - - //prop = System.getProperty("dns.search"); - //if (prop != null) { - // st = new StringTokenizer(prop, ","); - // while (st.hasMoreTokens()) - // addSearch(st.nextToken(), lsearch); - //} - configureFromLists(lserver, lsearch); - return (servers != null && searchlist != null); -} - -/** - * Uses the undocumented Sun DNS implementation to determine the configuration. - * This doesn't work or even compile with all JVMs (gcj, for example). - */ -private boolean -findSunJVM() { - List lserver = new ArrayList(0); - List lserver_tmp; - List lsearch = new ArrayList(0); - List lsearch_tmp; - - try { - Class [] noClasses = new Class[0]; - Object [] noObjects = new Object[0]; - String resConfName = "sun.net.dns.ResolverConfiguration"; - Class resConfClass = Class.forName(resConfName); - Object resConf; - - // ResolverConfiguration resConf = ResolverConfiguration.open(); - Method open = resConfClass.getDeclaredMethod("open", noClasses); - resConf = open.invoke(null, noObjects); - - // lserver_tmp = resConf.nameservers(); - Method nameservers = resConfClass.getMethod("nameservers", - noClasses); - lserver_tmp = (List) nameservers.invoke(resConf, noObjects); - - // lsearch_tmp = resConf.searchlist(); - Method searchlist = resConfClass.getMethod("searchlist", - noClasses); - lsearch_tmp = (List) searchlist.invoke(resConf, noObjects); - } - catch (Exception e) { - return false; - } - - if (lserver_tmp.size() == 0) - return false; - - if (lserver_tmp.size() > 0) { - Iterator it = lserver_tmp.iterator(); - while (it.hasNext()) - addServer((String) it.next(), lserver); - } - - if (lsearch_tmp.size() > 0) { - Iterator it = lsearch_tmp.iterator(); - while (it.hasNext()) - addSearch((String) it.next(), lsearch); - } - configureFromLists(lserver, lsearch); - return true; -} - -/** - * Looks in /etc/resolv.conf to find servers and a search path. - * "nameserver" lines specify servers. "domain" and "search" lines - * define the search path. - */ -private void -findResolvConf(String file) { - InputStream in = null; - try { - in = new FileInputStream(file); - } - catch (FileNotFoundException e) { - return; - } - InputStreamReader isr = new InputStreamReader(in); - BufferedReader br = new BufferedReader(isr); - List lserver = new ArrayList(0); - List lsearch = new ArrayList(0); - int lndots = -1; - try { - String line; - while ((line = br.readLine()) != null) { - if (line.startsWith("nameserver")) { - StringTokenizer st = new StringTokenizer(line); - st.nextToken(); /* skip nameserver */ - addServer(st.nextToken(), lserver); - } - else if (line.startsWith("domain")) { - StringTokenizer st = new StringTokenizer(line); - st.nextToken(); /* skip domain */ - if (!st.hasMoreTokens()) - continue; - if (lsearch.isEmpty()) - addSearch(st.nextToken(), lsearch); - } - else if (line.startsWith("search")) { - if (!lsearch.isEmpty()) - lsearch.clear(); - StringTokenizer st = new StringTokenizer(line); - st.nextToken(); /* skip search */ - while (st.hasMoreTokens()) - addSearch(st.nextToken(), lsearch); - } - else if(line.startsWith("options")) { - StringTokenizer st = new StringTokenizer(line); - st.nextToken(); /* skip options */ - while (st.hasMoreTokens()) { - String token = st.nextToken(); - if (token.startsWith("ndots:")) { - lndots = parseNdots(token); - } - } - } - } - br.close(); - } - catch (IOException e) { - } - - configureFromLists(lserver, lsearch); - configureNdots(lndots); -} - -private void -findUnix() { - findResolvConf("/etc/resolv.conf"); -} - -private void -findNetware() { - findResolvConf("sys:/etc/resolv.cfg"); -} - -/** - * Parses the output of winipcfg or ipconfig. - */ -private void -findWin(InputStream in, Locale locale) { - String packageName = ResolverConfig.class.getPackage().getName(); - String resPackageName = packageName + ".windows.DNSServer"; - ResourceBundle res; - if (locale != null) - res = ResourceBundle.getBundle(resPackageName, locale); - else - res = ResourceBundle.getBundle(resPackageName); - - String host_name = res.getString("host_name"); - String primary_dns_suffix = res.getString("primary_dns_suffix"); - String dns_suffix = res.getString("dns_suffix"); - String dns_servers = res.getString("dns_servers"); - - BufferedReader br = new BufferedReader(new InputStreamReader(in)); - try { - List lserver = new ArrayList(); - List lsearch = new ArrayList(); - String line = null; - boolean readingServers = false; - boolean readingSearches = false; - while ((line = br.readLine()) != null) { - StringTokenizer st = new StringTokenizer(line); - if (!st.hasMoreTokens()) { - readingServers = false; - readingSearches = false; - continue; - } - String s = st.nextToken(); - if (line.indexOf(":") != -1) { - readingServers = false; - readingSearches = false; - } - - if (line.indexOf(host_name) != -1) { - while (st.hasMoreTokens()) - s = st.nextToken(); - Name name; - try { - name = Name.fromString(s, null); - } - catch (TextParseException e) { - continue; - } - if (name.labels() == 1) - continue; - addSearch(s, lsearch); - } else if (line.indexOf(primary_dns_suffix) != -1) { - while (st.hasMoreTokens()) - s = st.nextToken(); - if (s.equals(":")) - continue; - addSearch(s, lsearch); - readingSearches = true; - } else if (readingSearches || - line.indexOf(dns_suffix) != -1) - { - while (st.hasMoreTokens()) - s = st.nextToken(); - if (s.equals(":")) - continue; - addSearch(s, lsearch); - readingSearches = true; - } else if (readingServers || - line.indexOf(dns_servers) != -1) - { - while (st.hasMoreTokens()) - s = st.nextToken(); - if (s.equals(":")) - continue; - addServer(s, lserver); - readingServers = true; - } - } - - configureFromLists(lserver, lsearch); - } - catch (IOException e) { - } - return; -} - -private void -findWin(InputStream in) { - String property = "org.xbill.DNS.windows.parse.buffer"; - final int defaultBufSize = 8 * 1024; - int bufSize = Integer.getInteger(property, defaultBufSize).intValue(); - BufferedInputStream b = new BufferedInputStream(in, bufSize); - b.mark(bufSize); - findWin(b, null); - if (servers == null) { - try { - b.reset(); - } - catch (IOException e) { - return; - } - findWin(b, new Locale("", "")); - } -} - -/** - * Calls winipcfg and parses the result to find servers and a search path. - */ -private void -find95() { - String s = "winipcfg.out"; - try { - Process p; - p = Runtime.getRuntime().exec("winipcfg /all /batch " + s); - p.waitFor(); - File f = new File(s); - findWin(new FileInputStream(f)); - new File(s).delete(); - } - catch (Exception e) { - return; - } -} - -/** - * Calls ipconfig and parses the result to find servers and a search path. - */ -private void -findNT() { - try { - Process p; - p = Runtime.getRuntime().exec("ipconfig /all"); - findWin(p.getInputStream()); - p.destroy(); - } - catch (Exception e) { - return; - } -} - -/** - * Parses the output of getprop, which is the only way to get DNS - * info on Android. getprop might disappear in future releases, so - * this code comes with a use-by date. - */ -private void -findAndroid() { - // This originally looked for all lines containing .dns; but - // http://code.google.com/p/android/issues/detail?id=2207#c73 - // indicates that net.dns* should always be the active nameservers, so - // we use those. - final String re1 = "^\\d+(\\.\\d+){3}$"; - final String re2 = "^[0-9a-f]+(:[0-9a-f]*)+:[0-9a-f]+$"; - ArrayList lserver = new ArrayList(); - ArrayList lsearch = new ArrayList(); - try { - Class SystemProperties = - Class.forName("android.os.SystemProperties"); - Method method = - SystemProperties.getMethod("get", - new Class[] { String.class }); - final String [] netdns = new String [] {"net.dns1", "net.dns2", - "net.dns3", "net.dns4"}; - for (int i = 0; i < netdns.length; i++) { - Object [] args = new Object [] { netdns[i] }; - String v = (String) method.invoke(null, args); - if (v != null && - (v.matches(re1) || v.matches(re2)) && - !lserver.contains(v)) - lserver.add(v); - } - } catch ( Exception e ) { - // ignore resolutely - } - configureFromLists(lserver, lsearch); -} - -/** Returns all located servers */ -public String [] -servers() { - return servers; -} - -/** Returns the first located server */ -public String -server() { - if (servers == null) - return null; - return servers[0]; -} - -/** Returns all entries in the located search path */ -public Name [] -searchPath() { - return searchlist; -} - -/** - * Returns the located ndots value, or the default (1) if not configured. - * Note that ndots can only be configured in a resolv.conf file, and will only - * take effect if ResolverConfig uses resolv.conf directly (that is, if the - * JVM does not include the sun.net.dns.ResolverConfiguration class). - */ -public int -ndots() { - if (ndots < 0) - return 1; - return ndots; -} - -/** Gets the current configuration */ -public static synchronized ResolverConfig -getCurrentConfig() { - return currentConfig; -} - -/** Gets the current configuration */ -public static void -refresh() { - ResolverConfig newConfig = new ResolverConfig(); - synchronized (ResolverConfig.class) { - currentConfig = newConfig; - } -} - -} diff --git a/src/main/java/core/org/xbill/DNS/ResolverListener.java b/src/main/java/core/org/xbill/DNS/ResolverListener.java deleted file mode 100644 index accf82c5..00000000 --- a/src/main/java/core/org/xbill/DNS/ResolverListener.java +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.EventListener; - -/** - * An interface to the asynchronous resolver. - * @see Resolver - * - * @author Brian Wellington - */ - -public interface ResolverListener extends EventListener { - -/** - * The callback used by an asynchronous resolver - * @param id The identifier returned by Resolver.sendAsync() - * @param m The response message as returned by the Resolver - */ -void receiveMessage(Object id, Message m); - -/** - * The callback used by an asynchronous resolver when an exception is thrown - * @param id The identifier returned by Resolver.sendAsync() - * @param e The thrown exception - */ -void handleException(Object id, Exception e); - -} diff --git a/src/main/java/core/org/xbill/DNS/ReverseMap.java b/src/main/java/core/org/xbill/DNS/ReverseMap.java deleted file mode 100644 index f4293dec..00000000 --- a/src/main/java/core/org/xbill/DNS/ReverseMap.java +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.net.*; - -/** - * A set functions designed to deal with DNS names used in reverse mappings. - * For the IPv4 address a.b.c.d, the reverse map name is d.c.b.a.in-addr.arpa. - * For an IPv6 address, the reverse map name is ...ip6.arpa. - * - * @author Brian Wellington - */ - -public final class ReverseMap { - -private static Name inaddr4 = Name.fromConstantString("in-addr.arpa."); -private static Name inaddr6 = Name.fromConstantString("ip6.arpa."); - -/* Otherwise the class could be instantiated */ -private -ReverseMap() {} - -/** - * Creates a reverse map name corresponding to an address contained in - * an array of 4 bytes (for an IPv4 address) or 16 bytes (for an IPv6 address). - * @param addr The address from which to build a name. - * @return The name corresponding to the address in the reverse map. - */ -public static Name -fromAddress(byte [] addr) { - if (addr.length != 4 && addr.length != 16) - throw new IllegalArgumentException("array must contain " + - "4 or 16 elements"); - - StringBuffer sb = new StringBuffer(); - if (addr.length == 4) { - for (int i = addr.length - 1; i >= 0; i--) { - sb.append(addr[i] & 0xFF); - if (i > 0) - sb.append("."); - } - } else { - int [] nibbles = new int[2]; - for (int i = addr.length - 1; i >= 0; i--) { - nibbles[0] = (addr[i] & 0xFF) >> 4; - nibbles[1] = (addr[i] & 0xFF) & 0xF; - for (int j = nibbles.length - 1; j >= 0; j--) { - sb.append(Integer.toHexString(nibbles[j])); - if (i > 0 || j > 0) - sb.append("."); - } - } - } - - try { - if (addr.length == 4) - return Name.fromString(sb.toString(), inaddr4); - else - return Name.fromString(sb.toString(), inaddr6); - } - catch (TextParseException e) { - throw new IllegalStateException("name cannot be invalid"); - } -} - -/** - * Creates a reverse map name corresponding to an address contained in - * an array of 4 integers between 0 and 255 (for an IPv4 address) or 16 - * integers between 0 and 255 (for an IPv6 address). - * @param addr The address from which to build a name. - * @return The name corresponding to the address in the reverse map. - */ -public static Name -fromAddress(int [] addr) { - byte [] bytes = new byte[addr.length]; - for (int i = 0; i < addr.length; i++) { - if (addr[i] < 0 || addr[i] > 0xFF) - throw new IllegalArgumentException("array must " + - "contain values " + - "between 0 and 255"); - bytes[i] = (byte) addr[i]; - } - return fromAddress(bytes); -} - -/** - * Creates a reverse map name corresponding to an address contained in - * an InetAddress. - * @param addr The address from which to build a name. - * @return The name corresponding to the address in the reverse map. - */ -public static Name -fromAddress(InetAddress addr) { - return fromAddress(addr.getAddress()); -} - -/** - * Creates a reverse map name corresponding to an address contained in - * a String. - * @param addr The address from which to build a name. - * @return The name corresponding to the address in the reverse map. - * @throws UnknownHostException The string does not contain a valid address. - */ -public static Name -fromAddress(String addr, int family) throws UnknownHostException { - byte [] array = Address.toByteArray(addr, family); - if (array == null) - throw new UnknownHostException("Invalid IP address"); - return fromAddress(array); -} - -/** - * Creates a reverse map name corresponding to an address contained in - * a String. - * @param addr The address from which to build a name. - * @return The name corresponding to the address in the reverse map. - * @throws UnknownHostException The string does not contain a valid address. - */ -public static Name -fromAddress(String addr) throws UnknownHostException { - byte [] array = Address.toByteArray(addr, Address.IPv4); - if (array == null) - array = Address.toByteArray(addr, Address.IPv6); - if (array == null) - throw new UnknownHostException("Invalid IP address"); - return fromAddress(array); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SIG0.java b/src/main/java/core/org/xbill/DNS/SIG0.java deleted file mode 100644 index 5a00e72a..00000000 --- a/src/main/java/core/org/xbill/DNS/SIG0.java +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2001-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.security.PrivateKey; -import java.util.Date; - -/** - * Creates SIG(0) transaction signatures. - * - * @author Pasi Eronen - * @author Brian Wellington - */ - -public class SIG0 { - -/** - * The default validity period for outgoing SIG(0) signed messages. - * Can be overriden by the sig0validity option. - */ -private static final short VALIDITY = 300; - -private -SIG0() { } - -/** - * Sign a message with SIG(0). The DNS key and private key must refer to the - * same underlying cryptographic key. - * @param message The message to be signed - * @param key The DNSKEY record to use as part of signing - * @param privkey The PrivateKey to use when signing - * @param previous If this message is a response, the SIG(0) from the query - */ -public static void -signMessage(Message message, KEYRecord key, PrivateKey privkey, - SIGRecord previous) throws DNSSEC.DNSSECException -{ - - int validity = Options.intValue("sig0validity"); - if (validity < 0) - validity = VALIDITY; - - long now = System.currentTimeMillis(); - Date timeSigned = new Date(now); - Date timeExpires = new Date(now + validity * 1000); - - SIGRecord sig = DNSSEC.signMessage(message, previous, key, privkey, - timeSigned, timeExpires); - - message.addRecord(sig, Section.ADDITIONAL); -} - -/** - * Verify a message using SIG(0). - * @param message The message to be signed - * @param b An array containing the message in unparsed form. This is - * necessary since SIG(0) signs the message in wire format, and we can't - * recreate the exact wire format (with the same name compression). - * @param key The KEY record to verify the signature with. - * @param previous If this message is a response, the SIG(0) from the query - */ -public static void -verifyMessage(Message message, byte [] b, KEYRecord key, SIGRecord previous) - throws DNSSEC.DNSSECException -{ - SIGRecord sig = null; - Record [] additional = message.getSectionArray(Section.ADDITIONAL); - for (int i = 0; i < additional.length; i++) { - if (additional[i].getType() != Type.SIG) - continue; - if (((SIGRecord) additional[i]).getTypeCovered() != 0) - continue; - sig = (SIGRecord) additional[i]; - break; - } - DNSSEC.verifyMessage(message, b, sig, previous, key); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SIGBase.java b/src/main/java/core/org/xbill/DNS/SIGBase.java deleted file mode 100644 index 6e5f12d6..00000000 --- a/src/main/java/core/org/xbill/DNS/SIGBase.java +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; -import org.xbill.DNS.utils.*; - -/** - * The base class for SIG/RRSIG records, which have identical formats - * - * @author Brian Wellington - */ - -abstract class SIGBase extends Record { - -private static final long serialVersionUID = -3738444391533812369L; - -protected int covered; -protected int alg, labels; -protected long origttl; -protected Date expire, timeSigned; -protected int footprint; -protected Name signer; -protected byte [] signature; - -protected -SIGBase() {} - -public -SIGBase(Name name, int type, int dclass, long ttl, int covered, int alg, - long origttl, Date expire, Date timeSigned, int footprint, Name signer, - byte [] signature) -{ - super(name, type, dclass, ttl); - Type.check(covered); - TTL.check(origttl); - this.covered = covered; - this.alg = checkU8("alg", alg); - this.labels = name.labels() - 1; - if (name.isWild()) - this.labels--; - this.origttl = origttl; - this.expire = expire; - this.timeSigned = timeSigned; - this.footprint = checkU16("footprint", footprint); - this.signer = checkName("signer", signer); - this.signature = signature; -} - -void -rrFromWire(DNSInput in) throws IOException { - covered = in.readU16(); - alg = in.readU8(); - labels = in.readU8(); - origttl = in.readU32(); - expire = new Date(1000 * in.readU32()); - timeSigned = new Date(1000 * in.readU32()); - footprint = in.readU16(); - signer = new Name(in); - signature = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - String typeString = st.getString(); - covered = Type.value(typeString); - if (covered < 0) - throw st.exception("Invalid type: " + typeString); - String algString = st.getString(); - alg = DNSSEC.Algorithm.value(algString); - if (alg < 0) - throw st.exception("Invalid algorithm: " + algString); - labels = st.getUInt8(); - origttl = st.getTTL(); - expire = FormattedTime.parse(st.getString()); - timeSigned = FormattedTime.parse(st.getString()); - footprint = st.getUInt16(); - signer = st.getName(origin); - signature = st.getBase64(); -} - -/** Converts the RRSIG/SIG Record to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append (Type.string(covered)); - sb.append (" "); - sb.append (alg); - sb.append (" "); - sb.append (labels); - sb.append (" "); - sb.append (origttl); - sb.append (" "); - if (Options.check("multiline")) - sb.append ("(\n\t"); - sb.append (FormattedTime.format(expire)); - sb.append (" "); - sb.append (FormattedTime.format(timeSigned)); - sb.append (" "); - sb.append (footprint); - sb.append (" "); - sb.append (signer); - if (Options.check("multiline")) { - sb.append("\n"); - sb.append(base64.formatString(signature, 64, "\t", - true)); - } else { - sb.append (" "); - sb.append(base64.toString(signature)); - } - return sb.toString(); -} - -/** Returns the RRset type covered by this signature */ -public int -getTypeCovered() { - return covered; -} - -/** - * Returns the cryptographic algorithm of the key that generated the signature - */ -public int -getAlgorithm() { - return alg; -} - -/** - * Returns the number of labels in the signed domain name. This may be - * different than the record's domain name if the record is a wildcard - * record. - */ -public int -getLabels() { - return labels; -} - -/** Returns the original TTL of the RRset */ -public long -getOrigTTL() { - return origttl; -} - -/** Returns the time at which the signature expires */ -public Date -getExpire() { - return expire; -} - -/** Returns the time at which this signature was generated */ -public Date -getTimeSigned() { - return timeSigned; -} - -/** Returns The footprint/key id of the signing key. */ -public int -getFootprint() { - return footprint; -} - -/** Returns the owner of the signing key */ -public Name -getSigner() { - return signer; -} - -/** Returns the binary data representing the signature */ -public byte [] -getSignature() { - return signature; -} - -void -setSignature(byte [] signature) { - this.signature = signature; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(covered); - out.writeU8(alg); - out.writeU8(labels); - out.writeU32(origttl); - out.writeU32(expire.getTime() / 1000); - out.writeU32(timeSigned.getTime() / 1000); - out.writeU16(footprint); - signer.toWire(out, null, canonical); - out.writeByteArray(signature); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SIGRecord.java b/src/main/java/core/org/xbill/DNS/SIGRecord.java deleted file mode 100644 index 8b6f58d7..00000000 --- a/src/main/java/core/org/xbill/DNS/SIGRecord.java +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.*; - -/** - * Signature - A SIG provides the digital signature of an RRset, so that - * the data can be authenticated by a DNSSEC-capable resolver. The - * signature is usually generated by a key contained in a KEYRecord - * @see RRset - * @see DNSSEC - * @see KEYRecord - * - * @author Brian Wellington - */ - -public class SIGRecord extends SIGBase { - -private static final long serialVersionUID = 4963556060953589058L; - -SIGRecord() {} - -Record -getObject() { - return new SIGRecord(); -} - -/** - * Creates an SIG Record from the given data - * @param covered The RRset type covered by this signature - * @param alg The cryptographic algorithm of the key that generated the - * signature - * @param origttl The original TTL of the RRset - * @param expire The time at which the signature expires - * @param timeSigned The time at which this signature was generated - * @param footprint The footprint/key id of the signing key. - * @param signer The owner of the signing key - * @param signature Binary data representing the signature - */ -public -SIGRecord(Name name, int dclass, long ttl, int covered, int alg, long origttl, - Date expire, Date timeSigned, int footprint, Name signer, - byte [] signature) -{ - super(name, Type.SIG, dclass, ttl, covered, alg, origttl, expire, - timeSigned, footprint, signer, signature); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SMIMEARecord.java b/src/main/java/core/org/xbill/DNS/SMIMEARecord.java deleted file mode 100644 index 09132c24..00000000 --- a/src/main/java/core/org/xbill/DNS/SMIMEARecord.java +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import org.xbill.DNS.utils.*; - -/** - * S/MIME cert association, draft-ietf-dane-smime. - * - * @author Brian Wellington - */ - -public class SMIMEARecord extends Record { - -private static final long serialVersionUID = 1640247915216425235L; - -// Note; these are copied from the TLSA type. - -public static class CertificateUsage { - private CertificateUsage() {} - - public static final int CA_CONSTRAINT = 0; - public static final int SERVICE_CERTIFICATE_CONSTRAINT = 1; - public static final int TRUST_ANCHOR_ASSERTION = 2; - public static final int DOMAIN_ISSUED_CERTIFICATE = 3; -} - -public static class Selector { - private Selector() {} - - /** - * Full certificate; the Certificate binary structure defined in - * [RFC5280] - */ - public static final int FULL_CERTIFICATE = 0; - - /** - * SubjectPublicKeyInfo; DER-encoded binary structure defined in - * [RFC5280] - */ - public static final int SUBJECT_PUBLIC_KEY_INFO = 1; -} - -public static class MatchingType { - private MatchingType() {} - - /** Exact match on selected content */ - public static final int EXACT = 0; - - /** SHA-256 hash of selected content [RFC6234] */ - public static final int SHA256 = 1; - - /** SHA-512 hash of selected content [RFC6234] */ - public static final int SHA512 = 2; -} - -private int certificateUsage; -private int selector; -private int matchingType; -private byte [] certificateAssociationData; - -SMIMEARecord() {} - -Record -getObject() { - return new SMIMEARecord(); -} - -/** - * Creates an SMIMEA Record from the given data - * @param certificateUsage The provided association that will be used to - * match the certificate presented in the S/MIME handshake. - * @param selector The part of the S/MIME certificate presented by the server - * that will be matched against the association data. - * @param matchingType How the certificate association is presented. - * @param certificateAssociationData The "certificate association data" to be - * matched. - */ -public -SMIMEARecord(Name name, int dclass, long ttl, - int certificateUsage, int selector, int matchingType, - byte [] certificateAssociationData) -{ - super(name, Type.SMIMEA, dclass, ttl); - this.certificateUsage = checkU8("certificateUsage", certificateUsage); - this.selector = checkU8("selector", selector); - this.matchingType = checkU8("matchingType", matchingType); - this.certificateAssociationData = checkByteArrayLength( - "certificateAssociationData", - certificateAssociationData, - 0xFFFF); -} - -void -rrFromWire(DNSInput in) throws IOException { - certificateUsage = in.readU8(); - selector = in.readU8(); - matchingType = in.readU8(); - certificateAssociationData = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - certificateUsage = st.getUInt8(); - selector = st.getUInt8(); - matchingType = st.getUInt8(); - certificateAssociationData = st.getHex(); -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(certificateUsage); - sb.append(" "); - sb.append(selector); - sb.append(" "); - sb.append(matchingType); - sb.append(" "); - sb.append(base16.toString(certificateAssociationData)); - - return sb.toString(); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU8(certificateUsage); - out.writeU8(selector); - out.writeU8(matchingType); - out.writeByteArray(certificateAssociationData); -} - -/** Returns the certificate usage of the SMIMEA record */ -public int -getCertificateUsage() { - return certificateUsage; -} - -/** Returns the selector of the SMIMEA record */ -public int -getSelector() { - return selector; -} - -/** Returns the matching type of the SMIMEA record */ -public int -getMatchingType() { - return matchingType; -} - -/** Returns the certificate associate data of this SMIMEA record */ -public final byte [] -getCertificateAssociationData() { - return certificateAssociationData; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SOARecord.java b/src/main/java/core/org/xbill/DNS/SOARecord.java deleted file mode 100644 index 7f27077a..00000000 --- a/src/main/java/core/org/xbill/DNS/SOARecord.java +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * Start of Authority - describes properties of a zone. - * - * @author Brian Wellington - */ - -public class SOARecord extends Record { - -private static final long serialVersionUID = 1049740098229303931L; - -private Name host, admin; -private long serial, refresh, retry, expire, minimum; - -SOARecord() {} - -Record -getObject() { - return new SOARecord(); -} - -/** - * Creates an SOA Record from the given data - * @param host The primary name server for the zone - * @param admin The zone administrator's address - * @param serial The zone's serial number - * @param refresh The amount of time until a secondary checks for a new serial - * number - * @param retry The amount of time between a secondary's checks for a new - * serial number - * @param expire The amount of time until a secondary expires a zone - * @param minimum The minimum TTL for records in the zone -*/ -public -SOARecord(Name name, int dclass, long ttl, Name host, Name admin, - long serial, long refresh, long retry, long expire, long minimum) -{ - super(name, Type.SOA, dclass, ttl); - this.host = checkName("host", host); - this.admin = checkName("admin", admin); - this.serial = checkU32("serial", serial); - this.refresh = checkU32("refresh", refresh); - this.retry = checkU32("retry", retry); - this.expire = checkU32("expire", expire); - this.minimum = checkU32("minimum", minimum); -} - -void -rrFromWire(DNSInput in) throws IOException { - host = new Name(in); - admin = new Name(in); - serial = in.readU32(); - refresh = in.readU32(); - retry = in.readU32(); - expire = in.readU32(); - minimum = in.readU32(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - host = st.getName(origin); - admin = st.getName(origin); - serial = st.getUInt32(); - refresh = st.getTTLLike(); - retry = st.getTTLLike(); - expire = st.getTTLLike(); - minimum = st.getTTLLike(); -} - -/** Convert to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(host); - sb.append(" "); - sb.append(admin); - if (Options.check("multiline")) { - sb.append(" (\n\t\t\t\t\t"); - sb.append(serial); - sb.append("\t; serial\n\t\t\t\t\t"); - sb.append(refresh); - sb.append("\t; refresh\n\t\t\t\t\t"); - sb.append(retry); - sb.append("\t; retry\n\t\t\t\t\t"); - sb.append(expire); - sb.append("\t; expire\n\t\t\t\t\t"); - sb.append(minimum); - sb.append(" )\t; minimum"); - } else { - sb.append(" "); - sb.append(serial); - sb.append(" "); - sb.append(refresh); - sb.append(" "); - sb.append(retry); - sb.append(" "); - sb.append(expire); - sb.append(" "); - sb.append(minimum); - } - return sb.toString(); -} - -/** Returns the primary name server */ -public Name -getHost() { - return host; -} - -/** Returns the zone administrator's address */ -public Name -getAdmin() { - return admin; -} - -/** Returns the zone's serial number */ -public long -getSerial() { - return serial; -} - -/** Returns the zone refresh interval */ -public long -getRefresh() { - return refresh; -} - -/** Returns the zone retry interval */ -public long -getRetry() { - return retry; -} - -/** Returns the time until a secondary expires a zone */ -public long -getExpire() { - return expire; -} - -/** Returns the minimum TTL for records in the zone */ -public long -getMinimum() { - return minimum; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - host.toWire(out, c, canonical); - admin.toWire(out, c, canonical); - out.writeU32(serial); - out.writeU32(refresh); - out.writeU32(retry); - out.writeU32(expire); - out.writeU32(minimum); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SPFRecord.java b/src/main/java/core/org/xbill/DNS/SPFRecord.java deleted file mode 100644 index a2862206..00000000 --- a/src/main/java/core/org/xbill/DNS/SPFRecord.java +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.*; - -/** - * Sender Policy Framework (RFC 4408, experimental) - * - * @author Brian Wellington - */ - -public class SPFRecord extends TXTBase { - -private static final long serialVersionUID = -2100754352801658722L; - -SPFRecord() {} - -Record -getObject() { - return new SPFRecord(); -} - -/** - * Creates a SPF Record from the given data - * @param strings The text strings - * @throws IllegalArgumentException One of the strings has invalid escapes - */ -public -SPFRecord(Name name, int dclass, long ttl, List strings) { - super(name, Type.SPF, dclass, ttl, strings); -} - -/** - * Creates a SPF Record from the given data - * @param string One text string - * @throws IllegalArgumentException The string has invalid escapes - */ -public -SPFRecord(Name name, int dclass, long ttl, String string) { - super(name, Type.SPF, dclass, ttl, string); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SRVRecord.java b/src/main/java/core/org/xbill/DNS/SRVRecord.java deleted file mode 100644 index c0635fbf..00000000 --- a/src/main/java/core/org/xbill/DNS/SRVRecord.java +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * Server Selection Record - finds hosts running services in a domain. An - * SRV record will normally be named _<service>._<protocol>.domain - * - examples would be _sips._tcp.example.org (for the secure SIP protocol) and - * _http._tcp.example.com (if HTTP used SRV records) - * - * @author Brian Wellington - */ - -public class SRVRecord extends Record { - -private static final long serialVersionUID = -3886460132387522052L; - -private int priority, weight, port; -private Name target; - -SRVRecord() {} - -Record -getObject() { - return new SRVRecord(); -} - -/** - * Creates an SRV Record from the given data - * @param priority The priority of this SRV. Records with lower priority - * are preferred. - * @param weight The weight, used to select between records at the same - * priority. - * @param port The TCP/UDP port that the service uses - * @param target The host running the service - */ -public -SRVRecord(Name name, int dclass, long ttl, int priority, - int weight, int port, Name target) -{ - super(name, Type.SRV, dclass, ttl); - this.priority = checkU16("priority", priority); - this.weight = checkU16("weight", weight); - this.port = checkU16("port", port); - this.target = checkName("target", target); -} - -void -rrFromWire(DNSInput in) throws IOException { - priority = in.readU16(); - weight = in.readU16(); - port = in.readU16(); - target = new Name(in); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - priority = st.getUInt16(); - weight = st.getUInt16(); - port = st.getUInt16(); - target = st.getName(origin); -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(priority + " "); - sb.append(weight + " "); - sb.append(port + " "); - sb.append(target); - return sb.toString(); -} - -/** Returns the priority */ -public int -getPriority() { - return priority; -} - -/** Returns the weight */ -public int -getWeight() { - return weight; -} - -/** Returns the port that the service runs on */ -public int -getPort() { - return port; -} - -/** Returns the host running that the service */ -public Name -getTarget() { - return target; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(priority); - out.writeU16(weight); - out.writeU16(port); - target.toWire(out, null, canonical); -} - -public Name -getAdditionalName() { - return target; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SSHFPRecord.java b/src/main/java/core/org/xbill/DNS/SSHFPRecord.java deleted file mode 100644 index 079741e2..00000000 --- a/src/main/java/core/org/xbill/DNS/SSHFPRecord.java +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import org.xbill.DNS.utils.*; - -/** - * SSH Fingerprint - stores the fingerprint of an SSH host key. - * - * @author Brian Wellington - */ - -public class SSHFPRecord extends Record { - -private static final long serialVersionUID = -8104701402654687025L; - -public static class Algorithm { - private Algorithm() {} - - public static final int RSA = 1; - public static final int DSS = 2; -} - -public static class Digest { - private Digest() {} - - public static final int SHA1 = 1; -} - -private int alg; -private int digestType; -private byte [] fingerprint; - -SSHFPRecord() {} - -Record -getObject() { - return new SSHFPRecord(); -} - -/** - * Creates an SSHFP Record from the given data. - * @param alg The public key's algorithm. - * @param digestType The public key's digest type. - * @param fingerprint The public key's fingerprint. - */ -public -SSHFPRecord(Name name, int dclass, long ttl, int alg, int digestType, - byte [] fingerprint) -{ - super(name, Type.SSHFP, dclass, ttl); - this.alg = checkU8("alg", alg); - this.digestType = checkU8("digestType", digestType); - this.fingerprint = fingerprint; -} - -void -rrFromWire(DNSInput in) throws IOException { - alg = in.readU8(); - digestType = in.readU8(); - fingerprint = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - alg = st.getUInt8(); - digestType = st.getUInt8(); - fingerprint = st.getHex(true); -} - -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(alg); - sb.append(" "); - sb.append(digestType); - sb.append(" "); - sb.append(base16.toString(fingerprint)); - return sb.toString(); -} - -/** Returns the public key's algorithm. */ -public int -getAlgorithm() { - return alg; -} - -/** Returns the public key's digest type. */ -public int -getDigestType() { - return digestType; -} - -/** Returns the fingerprint */ -public byte [] -getFingerPrint() { - return fingerprint; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU8(alg); - out.writeU8(digestType); - out.writeByteArray(fingerprint); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SVCBBase.java b/src/main/java/core/org/xbill/DNS/SVCBBase.java deleted file mode 100644 index a497e012..00000000 --- a/src/main/java/core/org/xbill/DNS/SVCBBase.java +++ /dev/null @@ -1,753 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -package org.xbill.DNS; - -import java.io.IOException; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Base64; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -/** Implements common functionality for SVCB and HTTPS records */ -abstract class SVCBBase extends Record { - protected int svcPriority; - protected Name targetName; - protected final Map svcParams; - - public static final int MANDATORY = 0; - public static final int ALPN = 1; - public static final int NO_DEFAULT_ALPN = 2; - public static final int PORT = 3; - public static final int IPV4HINT = 4; - public static final int ECHCONFIG = 5; - public static final int IPV6HINT = 6; - - protected SVCBBase() { - svcParams = new TreeMap<>(); - } - - protected SVCBBase(Name name, int type, int dclass, long ttl) { - super(name, type, dclass, ttl); - svcParams = new TreeMap<>(); - } - - protected SVCBBase( - Name name, - int type, - int dclass, - long ttl, - int priority, - Name domain, - List params) { - super(name, type, dclass, ttl); - svcPriority = priority; - targetName = domain; - svcParams = new TreeMap<>(); - for (ParameterBase param : params) { - if (svcParams.containsKey(param.getKey())) { - throw new IllegalArgumentException("Duplicate SvcParam for key " + param.getKey()); - } - svcParams.put(param.getKey(), param); - } - } - - public int getSvcPriority() { - return svcPriority; - } - - public Name getTargetName() { - return targetName; - } - - public Set getSvcParamKeys() { - return svcParams.keySet(); - } - - public ParameterBase getSvcParamValue(int key) { - return svcParams.get(key); - } - - private static class ParameterMnemonic extends Mnemonic { - private HashMap> factories; - - public ParameterMnemonic() { - super("SVCB/HTTPS Parameters", Mnemonic.CASE_LOWER); - setPrefix("key"); - setNumericAllowed(true); - setMaximum(0xFFFF); - factories = new HashMap<>(); - } - - public void add(int val, String str, Supplier factory) { - super.add(val, str); - factories.put(val, factory); - } - - public Supplier getFactory(int val) { - return factories.get(val); - } - } - - private static final ParameterMnemonic parameters = new ParameterMnemonic(); - - static { - parameters.add(MANDATORY, "mandatory", ParameterMandatory::new); - parameters.add(ALPN, "alpn", ParameterAlpn::new); - parameters.add(NO_DEFAULT_ALPN, "no-default-alpn", ParameterNoDefaultAlpn::new); - parameters.add(PORT, "port", ParameterPort::new); - parameters.add(IPV4HINT, "ipv4hint", ParameterIpv4Hint::new); - parameters.add(ECHCONFIG, "echconfig", ParameterEchConfig::new); - parameters.add(IPV6HINT, "ipv6hint", ParameterIpv6Hint::new); - } - - public abstract static class ParameterBase { - public ParameterBase() {} - - public abstract int getKey(); - - public abstract void fromWire(byte[] bytes) throws IOException; - - public abstract void fromString(String string) throws IOException; - - public abstract byte[] toWire(); - - public abstract String toString(); - - // Split string on commas, but not if comma is escaped with a '\' - public static String[] splitStringWithEscapedCommas(String string) { - return string.split("(? values; - - public ParameterMandatory() { - super(); - values = new ArrayList<>(); - } - - public ParameterMandatory(List values) { - super(); - this.values = values; - } - - public List getValues() { - return values; - } - - @Override - public int getKey() { - return MANDATORY; - } - - @Override - public void fromWire(byte[] bytes) throws IOException { - values.clear(); - DNSInput in = new DNSInput(bytes); - while (in.remaining() >= 2) { - int key = in.readU16(); - values.add(key); - } - if (in.remaining() > 0) { - throw new WireParseException("Unexpected number of bytes in mandatory parameter"); - } - } - - @Override - public void fromString(String string) throws TextParseException { - values.clear(); - if (string == null || string.isEmpty()) { - throw new TextParseException("Non-empty list must be specified for mandatory"); - } - for (String str : splitStringWithEscapedCommas(string)) { - int key = parameters.getValue(str); - if (key == MANDATORY) { - throw new TextParseException("Key mandatory must not appear in its own list"); - } - if (values.contains(key)) { - throw new TextParseException("Duplicate key " + str + " not allowed in mandatory list"); - } - values.add(key); - } - } - - @Override - public byte[] toWire() { - DNSOutput out = new DNSOutput(); - for (Integer val : values) { - out.writeU16(val); - } - return out.toByteArray(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (Integer val : values) { - if (sb.length() > 0) { - sb.append(","); - } - sb.append(parameters.getText(val)); - } - return sb.toString(); - } - } - - public static class ParameterAlpn extends ParameterBase { - private final List values; - - public ParameterAlpn() { - super(); - values = new ArrayList<>(); - } - - public ParameterAlpn(List values) { - super(); - this.values = - values.stream() - .map(s -> s.getBytes(StandardCharsets.US_ASCII)) - .collect(Collectors.toList()); - } - - public List getValues() { - return values.stream() - .map(b -> new String(b, StandardCharsets.US_ASCII)) - .collect(Collectors.toList()); - } - - @Override - public int getKey() { - return ALPN; - } - - @Override - public void fromWire(byte[] bytes) throws IOException { - values.clear(); - DNSInput in = new DNSInput(bytes); - while (in.remaining() > 0) { - byte[] b = in.readCountedString(); - values.add(b); - } - } - - @Override - public void fromString(String string) throws TextParseException { - values.clear(); - if (string == null || string.isEmpty()) { - throw new TextParseException("Non-empty list must be specified for alpn"); - } - for (String str : splitStringWithEscapedCommas(string)) { - values.add(str.getBytes()); - } - } - - @Override - public byte[] toWire() { - DNSOutput out = new DNSOutput(); - for (byte[] b : values) { - out.writeCountedString(b); - } - return out.toByteArray(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (byte[] b : values) { - if (sb.length() > 0) { - sb.append(","); - } - sb.append(new String(b)); - } - return sb.toString(); - } - } - - public static class ParameterNoDefaultAlpn extends ParameterBase { - public ParameterNoDefaultAlpn() { - super(); - } - - @Override - public int getKey() { - return NO_DEFAULT_ALPN; - } - - @Override - public void fromWire(byte[] bytes) throws WireParseException { - if (bytes.length > 0) { - throw new WireParseException("No value can be specified for no-default-alpn"); - } - } - - @Override - public void fromString(String string) throws TextParseException { - if (string != null && !string.isEmpty()) { - throw new TextParseException("No value can be specified for no-default-alpn"); - } - } - - @Override - public byte[] toWire() { - return new byte[0]; - } - - @Override - public String toString() { - return ""; - } - } - - public static class ParameterPort extends ParameterBase { - private int port; - - public ParameterPort() { - super(); - } - - public ParameterPort(int port) { - super(); - this.port = port; - } - - public int getPort() { - return port; - } - - @Override - public int getKey() { - return PORT; - } - - @Override - public void fromWire(byte[] bytes) throws IOException { - DNSInput in = new DNSInput(bytes); - port = in.readU16(); - if (in.remaining() > 0) { - throw new WireParseException("Unexpected number of bytes in port parameter"); - } - } - - @Override - public void fromString(String string) throws TextParseException { - if (string == null || string.isEmpty()) { - throw new TextParseException("Integer value must be specified for port"); - } - port = Integer.parseInt(string); - } - - @Override - public byte[] toWire() { - DNSOutput out = new DNSOutput(); - out.writeU16(port); - return out.toByteArray(); - } - - @Override - public String toString() { - return Integer.toString(port); - } - } - - public static class ParameterIpv4Hint extends ParameterBase { - private final List addresses; - - public ParameterIpv4Hint() { - super(); - addresses = new ArrayList<>(); - } - - public ParameterIpv4Hint(List addresses) { - super(); - this.addresses = - addresses.stream().map(Inet4Address::getAddress).collect(Collectors.toList()); - } - - public List getAddresses() throws UnknownHostException { - List addresses = new LinkedList<>(); - for (byte[] bytes : this.addresses) { - InetAddress address = InetAddress.getByAddress(bytes); - if (address instanceof Inet4Address) { - addresses.add((Inet4Address) address); - } - } - return addresses; - } - - @Override - public int getKey() { - return IPV4HINT; - } - - @Override - public void fromWire(byte[] bytes) throws IOException { - addresses.clear(); - DNSInput in = new DNSInput(bytes); - while (in.remaining() >= 4) { - addresses.add(in.readByteArray(4)); - } - if (in.remaining() > 0) { - throw new WireParseException("Unexpected number of bytes in ipv4hint parameter"); - } - } - - @Override - public void fromString(String string) throws IOException { - addresses.clear(); - if (string == null || string.isEmpty()) { - throw new TextParseException("Non-empty IPv4 list must be specified for ipv4hint"); - } - for (String str : string.split(",")) { - byte[] address = Address.toByteArray(str, Address.IPv4); - if (address == null) { - throw new TextParseException("Invalid ipv4hint value '" + str + "'"); - } - addresses.add(address); - } - } - - @Override - public byte[] toWire() { - DNSOutput out = new DNSOutput(); - for (byte[] b : addresses) { - out.writeByteArray(b); - } - return out.toByteArray(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (byte[] b : addresses) { - if (sb.length() > 0) { - sb.append(","); - } - sb.append(Address.toDottedQuad(b)); - } - return sb.toString(); - } - } - - public static class ParameterEchConfig extends ParameterBase { - private byte[] data; - - public ParameterEchConfig() { - super(); - } - - public ParameterEchConfig(byte[] data) { - super(); - this.data = data; - } - - public byte[] getData() { - return data; - } - - @Override - public int getKey() { - return ECHCONFIG; - } - - @Override - public void fromWire(byte[] bytes) { - data = bytes; - } - - @Override - public void fromString(String string) throws TextParseException { - if (string == null || string.isEmpty()) { - throw new TextParseException("Non-empty base64 value must be specified for echconfig"); - } - data = Base64.getDecoder().decode(string); - } - - @Override - public byte[] toWire() { - return data; - } - - @Override - public String toString() { - return Base64.getEncoder().encodeToString(data); - } - } - - public static class ParameterIpv6Hint extends ParameterBase { - private final List addresses; - - public ParameterIpv6Hint() { - super(); - addresses = new ArrayList<>(); - } - - public ParameterIpv6Hint(List addresses) { - super(); - this.addresses = - addresses.stream().map(Inet6Address::getAddress).collect(Collectors.toList()); - } - - public List getAddresses() throws UnknownHostException { - List addresses = new LinkedList<>(); - for (byte[] bytes : this.addresses) { - InetAddress address = InetAddress.getByAddress(bytes); - if (address instanceof Inet6Address) { - addresses.add((Inet6Address) address); - } - } - return addresses; - } - - @Override - public int getKey() { - return IPV6HINT; - } - - @Override - public void fromWire(byte[] bytes) throws IOException { - addresses.clear(); - DNSInput in = new DNSInput(bytes); - while (in.remaining() >= 16) { - addresses.add(in.readByteArray(16)); - } - if (in.remaining() > 0) { - throw new WireParseException("Unexpected number of bytes in ipv6hint parameter"); - } - } - - @Override - public void fromString(String string) throws IOException { - addresses.clear(); - if (string == null || string.isEmpty()) { - throw new TextParseException("Non-empty IPv6 list must be specified for ipv6hint"); - } - for (String str : string.split(",")) { - byte[] address = Address.toByteArray(str, Address.IPv6); - if (address == null) { - throw new TextParseException("Invalid ipv6hint value '" + str + "'"); - } - addresses.add(address); - } - } - - @Override - public byte[] toWire() { - DNSOutput out = new DNSOutput(); - for (byte[] b : addresses) { - out.writeByteArray(b); - } - return out.toByteArray(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (byte[] b : addresses) { - if (sb.length() > 0) { - sb.append(","); - } - try { - InetAddress addr = InetAddress.getByAddress(null, b); - sb.append(addr.getCanonicalHostName()); - } catch (UnknownHostException e) { - return null; - } - } - return sb.toString(); - } - } - - public static class ParameterUnknown extends ParameterBase { - private int key; - private byte[] value; - - public ParameterUnknown(int key) { - super(); - this.key = key; - this.value = new byte[0]; - } - - public ParameterUnknown(int key, byte[] value) { - super(); - this.key = key; - this.value = value; - } - - public byte[] getValue() { - return value; - } - - @Override - public int getKey() { - return key; - } - - @Override - public void fromWire(byte[] bytes) { - value = bytes; - } - - @Override - public void fromString(String string) throws IOException { - if (string == null || string.isEmpty()) { - value = new byte[0]; - } else { - value = byteArrayFromString(string); - } - } - - @Override - public byte[] toWire() { - return value; - } - - @Override - public String toString() { - return byteArrayToString(value, false); - } - } - - protected boolean checkMandatoryParams() { - ParameterMandatory param = (ParameterMandatory) getSvcParamValue(MANDATORY); - if (param != null) { - for (int key : param.values) { - if (getSvcParamValue(key) == null) { - return false; - } - } - } - return true; - } - - @Override - protected void rrFromWire(DNSInput in) throws IOException { - svcPriority = in.readU16(); - targetName = new Name(in); - svcParams.clear(); - while (in.remaining() >= 4) { - int key = in.readU16(); - int length = in.readU16(); - byte[] value = in.readByteArray(length); - ParameterBase param; - Supplier factory = parameters.getFactory(key); - if (factory != null) { - param = factory.get(); - } else { - param = new ParameterUnknown(key); - } - param.fromWire(value); - svcParams.put(key, param); - } - if (in.remaining() > 0) { - throw new WireParseException("Record had unexpected number of bytes"); - } - if (!checkMandatoryParams()) { - throw new WireParseException("Not all mandatory SvcParams are specified"); - } - } - - @Override - protected String rrToString() { - StringBuilder sb = new StringBuilder(); - sb.append(svcPriority); - sb.append(" "); - sb.append(targetName); - for (Integer key : svcParams.keySet()) { - sb.append(" "); - sb.append(parameters.getText(key)); - ParameterBase param = svcParams.get(key); - String value = param.toString(); - if (value != null && !value.isEmpty()) { - sb.append("="); - sb.append(value); - } - } - return sb.toString(); - } - - @Override - protected void rdataFromString(Tokenizer st, Name origin) throws IOException { - svcPriority = st.getUInt16(); - targetName = st.getName(origin); - svcParams.clear(); - while (true) { - String keyStr = null; - String valueStr = null; - Tokenizer.Token t = st.get(); - if (!t.isString()) { - break; - } - int indexOfEquals = t.value.indexOf('='); - if (indexOfEquals == -1) { - // No "=" is key with no value case, leave value string as null - keyStr = t.value; - } else if (indexOfEquals == t.value.length() - 1) { - // Ends with "=" means the next token is quoted string with the value - keyStr = t.value.substring(0, indexOfEquals); - Tokenizer.Token valueToken = st.get(); - if (!valueToken.isString()) { - throw new TextParseException("Expected value for parameter key '" + keyStr + "'"); - } - valueStr = valueToken.value; - } else if (indexOfEquals > 0) { - // If "=" is in the middle then need to split the key and value from this token - keyStr = t.value.substring(0, indexOfEquals); - valueStr = t.value.substring(indexOfEquals + 1); - } else { - throw new TextParseException("Expected valid parameter key=value for '" + t.value + "'"); - } - - ParameterBase param; - int key = parameters.getValue(keyStr); - if (key == -1) { - throw new TextParseException("Expected a valid parameter key for '" + keyStr + "'"); - } - if (svcParams.containsKey(key)) { - throw new TextParseException("Duplicate parameter key for '" + keyStr + "'"); - } - Supplier factory = parameters.getFactory(key); - if (factory != null) { - param = factory.get(); - } else { - param = new ParameterUnknown(key); - } - param.fromString(valueStr); - svcParams.put(key, param); - } - - if (svcPriority > 0 && svcParams.isEmpty()) { - throw new TextParseException( - "At least one parameter value must be specified for ServiceMode"); - } - if (svcPriority == 0 && !svcParams.isEmpty()) { - throw new TextParseException("No parameter values allowed for AliasMode"); - } - if (!checkMandatoryParams()) { - throw new TextParseException("Not all mandatory SvcParams are specified"); - } - } - - @Override - protected void rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(svcPriority); - targetName.toWire(out, null, canonical); - for (Integer key : svcParams.keySet()) { - out.writeU16(key); - ParameterBase param = svcParams.get(key); - byte[] value = param.toWire(); - out.writeU16(value.length); - out.writeByteArray(value); - } - } -} \ No newline at end of file diff --git a/src/main/java/core/org/xbill/DNS/SVCBRecord.java b/src/main/java/core/org/xbill/DNS/SVCBRecord.java deleted file mode 100644 index 7de7761e..00000000 --- a/src/main/java/core/org/xbill/DNS/SVCBRecord.java +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -package org.xbill.DNS; - -import java.util.List; - -/** - * Service Location and Parameter Binding Record - * - * @see draft-ietf-dnsop-svcb-https - */ -public class SVCBRecord extends SVCBBase { - SVCBRecord() {} - - public SVCBRecord( - Name name, int dclass, long ttl, int priority, Name domain, List params) { - super(name, Type.SVCB, dclass, ttl, priority, domain, params); - } - - Record getObject() { - return new SVCBRecord(); - } -} diff --git a/src/main/java/core/org/xbill/DNS/Section.java b/src/main/java/core/org/xbill/DNS/Section.java deleted file mode 100644 index e0c8caab..00000000 --- a/src/main/java/core/org/xbill/DNS/Section.java +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Constants and functions relating to DNS message sections - * - * @author Brian Wellington - */ - -public final class Section { - -/** The question (first) section */ -public static final int QUESTION = 0; - -/** The answer (second) section */ -public static final int ANSWER = 1; - -/** The authority (third) section */ -public static final int AUTHORITY = 2; - -/** The additional (fourth) section */ -public static final int ADDITIONAL = 3; - -/* Aliases for dynamic update */ -/** The zone (first) section of a dynamic update message */ -public static final int ZONE = 0; - -/** The prerequisite (second) section of a dynamic update message */ -public static final int PREREQ = 1; - -/** The update (third) section of a dynamic update message */ -public static final int UPDATE = 2; - -private static Mnemonic sections = new Mnemonic("Message Section", - Mnemonic.CASE_LOWER); -private static String [] longSections = new String[4]; -private static String [] updateSections = new String[4]; - -static { - sections.setMaximum(3); - sections.setNumericAllowed(true); - - sections.add(QUESTION, "qd"); - sections.add(ANSWER, "an"); - sections.add(AUTHORITY, "au"); - sections.add(ADDITIONAL, "ad"); - - longSections[QUESTION] = "QUESTIONS"; - longSections[ANSWER] = "ANSWERS"; - longSections[AUTHORITY] = "AUTHORITY RECORDS"; - longSections[ADDITIONAL] = "ADDITIONAL RECORDS"; - - updateSections[ZONE] = "ZONE"; - updateSections[PREREQ] = "PREREQUISITES"; - updateSections[UPDATE] = "UPDATE RECORDS"; - updateSections[ADDITIONAL] = "ADDITIONAL RECORDS"; -} - -private -Section() {} - -/** Converts a numeric Section into an abbreviation String */ -public static String -string(int i) { - return sections.getText(i); -} - -/** Converts a numeric Section into a full description String */ -public static String -longString(int i) { - sections.check(i); - return longSections[i]; -} - -/** - * Converts a numeric Section into a full description String for an update - * Message. - */ -public static String -updString(int i) { - sections.check(i); - return updateSections[i]; -} - -/** Converts a String representation of a Section into its numeric value */ -public static int -value(String s) { - return sections.getValue(s); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Serial.java b/src/main/java/core/org/xbill/DNS/Serial.java deleted file mode 100644 index 3a146c65..00000000 --- a/src/main/java/core/org/xbill/DNS/Serial.java +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Helper functions for doing serial arithmetic. These should be used when - * setting/checking SOA serial numbers. SOA serial number arithmetic is - * defined in RFC 1982. - * - * @author Brian Wellington - */ - -public final class Serial { - -private static final long MAX32 = 0xFFFFFFFFL; - -private -Serial() { -} - -/** - * Compares two numbers using serial arithmetic. The numbers are assumed - * to be 32 bit unsigned integers stored in longs. - * @param serial1 The first integer - * @param serial2 The second integer - * @return 0 if the 2 numbers are equal, a positive number if serial1 is greater - * than serial2, and a negative number if serial2 is greater than serial1. - * @throws IllegalArgumentException serial1 or serial2 is out of range - */ -public static int -compare(long serial1, long serial2) { - if (serial1 < 0 || serial1 > MAX32) - throw new IllegalArgumentException(serial1 + " out of range"); - if (serial2 < 0 || serial2 > MAX32) - throw new IllegalArgumentException(serial2 + " out of range"); - long diff = serial1 - serial2; - if (diff >= MAX32) - diff -= (MAX32 + 1); - else if (diff < -MAX32) - diff += (MAX32 + 1); - return (int)diff; -} - -/** - * Increments a serial number. The number is assumed to be a 32 bit unsigned - * integer stored in a long. This basically adds 1 and resets the value to - * 0 if it is 2^32. - * @param serial The serial number - * @return The incremented serial number - * @throws IllegalArgumentException serial is out of range - */ -public static long -increment(long serial) { - if (serial < 0 || serial > MAX32) - throw new IllegalArgumentException(serial + " out of range"); - if (serial == MAX32) - return 0; - return serial + 1; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SetResponse.java b/src/main/java/core/org/xbill/DNS/SetResponse.java deleted file mode 100644 index 05d9f326..00000000 --- a/src/main/java/core/org/xbill/DNS/SetResponse.java +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.*; - -/** - * The Response from a query to Cache.lookupRecords() or Zone.findRecords() - * @see Cache - * @see Zone - * - * @author Brian Wellington - */ - -public class SetResponse { - -/** - * The Cache contains no information about the requested name/type - */ -static final int UNKNOWN = 0; - -/** - * The Zone does not contain the requested name, or the Cache has - * determined that the name does not exist. - */ -static final int NXDOMAIN = 1; - -/** - * The Zone contains the name, but no data of the requested type, - * or the Cache has determined that the name exists and has no data - * of the requested type. - */ -static final int NXRRSET = 2; - -/** - * A delegation enclosing the requested name was found. - */ -static final int DELEGATION = 3; - -/** - * The Cache/Zone found a CNAME when looking for the name. - * @see CNAMERecord - */ -static final int CNAME = 4; - -/** - * The Cache/Zone found a DNAME when looking for the name. - * @see DNAMERecord - */ -static final int DNAME = 5; - -/** - * The Cache/Zone has successfully answered the question for the - * requested name/type/class. - */ -static final int SUCCESSFUL = 6; - -private static final SetResponse unknown = new SetResponse(UNKNOWN); -private static final SetResponse nxdomain = new SetResponse(NXDOMAIN); -private static final SetResponse nxrrset = new SetResponse(NXRRSET); - -private int type; -private Object data; - -private -SetResponse() {} - -SetResponse(int type, RRset rrset) { - if (type < 0 || type > 6) - throw new IllegalArgumentException("invalid type"); - this.type = type; - this.data = rrset; -} - -SetResponse(int type) { - if (type < 0 || type > 6) - throw new IllegalArgumentException("invalid type"); - this.type = type; - this.data = null; -} - -static SetResponse -ofType(int type) { - switch (type) { - case UNKNOWN: - return unknown; - case NXDOMAIN: - return nxdomain; - case NXRRSET: - return nxrrset; - case DELEGATION: - case CNAME: - case DNAME: - case SUCCESSFUL: - SetResponse sr = new SetResponse(); - sr.type = type; - sr.data = null; - return sr; - default: - throw new IllegalArgumentException("invalid type"); - } -} - -void -addRRset(RRset rrset) { - if (data == null) - data = new ArrayList(); - List l = (List) data; - l.add(rrset); -} - -/** Is the answer to the query unknown? */ -public boolean -isUnknown() { - return (type == UNKNOWN); -} - -/** Is the answer to the query that the name does not exist? */ -public boolean -isNXDOMAIN() { - return (type == NXDOMAIN); -} - -/** Is the answer to the query that the name exists, but the type does not? */ -public boolean -isNXRRSET() { - return (type == NXRRSET); -} - -/** Is the result of the lookup that the name is below a delegation? */ -public boolean -isDelegation() { - return (type == DELEGATION); -} - -/** Is the result of the lookup a CNAME? */ -public boolean -isCNAME() { - return (type == CNAME); -} - -/** Is the result of the lookup a DNAME? */ -public boolean -isDNAME() { - return (type == DNAME); -} - -/** Was the query successful? */ -public boolean -isSuccessful() { - return (type == SUCCESSFUL); -} - -/** If the query was successful, return the answers */ -public RRset [] -answers() { - if (type != SUCCESSFUL) - return null; - List l = (List) data; - return (RRset []) l.toArray(new RRset[l.size()]); -} - -/** - * If the query encountered a CNAME, return it. - */ -public CNAMERecord -getCNAME() { - return (CNAMERecord)((RRset)data).first(); -} - -/** - * If the query encountered a DNAME, return it. - */ -public DNAMERecord -getDNAME() { - return (DNAMERecord)((RRset)data).first(); -} - -/** - * If the query hit a delegation point, return the NS set. - */ -public RRset -getNS() { - return (RRset)data; -} - -/** Prints the value of the SetResponse */ -public String -toString() { - switch (type) { - case UNKNOWN: return "unknown"; - case NXDOMAIN: return "NXDOMAIN"; - case NXRRSET: return "NXRRSET"; - case DELEGATION: return "delegation: " + data; - case CNAME: return "CNAME: " + data; - case DNAME: return "DNAME: " + data; - case SUCCESSFUL: return "successful"; - default: throw new IllegalStateException(); - } -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SimpleResolver.java b/src/main/java/core/org/xbill/DNS/SimpleResolver.java deleted file mode 100644 index 9a3ab369..00000000 --- a/src/main/java/core/org/xbill/DNS/SimpleResolver.java +++ /dev/null @@ -1,351 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.*; -import java.io.*; -import java.net.*; - -/** - * An implementation of Resolver that sends one query to one server. - * SimpleResolver handles TCP retries, transaction security (TSIG), and - * EDNS 0. - * @see Resolver - * @see TSIG - * @see OPTRecord - * - * @author Brian Wellington - */ - - -public class SimpleResolver implements Resolver { - -/** The default port to send queries to */ -public static final int DEFAULT_PORT = 53; - -/** The default EDNS payload size */ -public static final int DEFAULT_EDNS_PAYLOADSIZE = 1280; - -private InetSocketAddress address; -private InetSocketAddress localAddress; -private boolean useTCP, ignoreTruncation; -private OPTRecord queryOPT; -private TSIG tsig; -private long timeoutValue = 10 * 1000; - -private static final short DEFAULT_UDPSIZE = 512; - -private static String defaultResolver = "localhost"; -private static int uniqueID = 0; - -/** - * Creates a SimpleResolver that will query the specified host - * @exception UnknownHostException Failure occurred while finding the host - */ -public -SimpleResolver(String hostname) throws UnknownHostException { - if (hostname == null) { - hostname = ResolverConfig.getCurrentConfig().server(); - if (hostname == null) - hostname = defaultResolver; - } - InetAddress addr; - if (hostname.equals("0")) - addr = InetAddress.getLocalHost(); - else - addr = InetAddress.getByName(hostname); - address = new InetSocketAddress(addr, DEFAULT_PORT); -} - -/** - * Creates a SimpleResolver. The host to query is either found by using - * ResolverConfig, or the default host is used. - * @see ResolverConfig - * @exception UnknownHostException Failure occurred while finding the host - */ -public -SimpleResolver() throws UnknownHostException { - this(null); -} - -/** - * Gets the destination address associated with this SimpleResolver. - * Messages sent using this SimpleResolver will be sent to this address. - * @return The destination address associated with this SimpleResolver. - */ -public InetSocketAddress -getAddress() { - return address; -} - -/** Sets the default host (initially localhost) to query */ -public static void -setDefaultResolver(String hostname) { - defaultResolver = hostname; -} - -public void -setPort(int port) { - address = new InetSocketAddress(address.getAddress(), port); -} - -/** - * Sets the address of the server to communicate with. - * @param addr The address of the DNS server - */ -public void -setAddress(InetSocketAddress addr) { - address = addr; -} - -/** - * Sets the address of the server to communicate with (on the default - * DNS port) - * @param addr The address of the DNS server - */ -public void -setAddress(InetAddress addr) { - address = new InetSocketAddress(addr, address.getPort()); -} - -/** - * Sets the local address to bind to when sending messages. - * @param addr The local address to send messages from. - */ -public void -setLocalAddress(InetSocketAddress addr) { - localAddress = addr; -} - -/** - * Sets the local address to bind to when sending messages. A random port - * will be used. - * @param addr The local address to send messages from. - */ -public void -setLocalAddress(InetAddress addr) { - localAddress = new InetSocketAddress(addr, 0); -} - -public void -setTCP(boolean flag) { - this.useTCP = flag; -} - -public void -setIgnoreTruncation(boolean flag) { - this.ignoreTruncation = flag; -} - -public void -setEDNS(int level, int payloadSize, int flags, List options) { - if (level != 0 && level != -1) - throw new IllegalArgumentException("invalid EDNS level - " + - "must be 0 or -1"); - if (payloadSize == 0) - payloadSize = DEFAULT_EDNS_PAYLOADSIZE; - queryOPT = new OPTRecord(payloadSize, 0, level, flags, options); -} - -public void -setEDNS(int level) { - setEDNS(level, 0, 0, null); -} - -public void -setTSIGKey(TSIG key) { - tsig = key; -} - -TSIG -getTSIGKey() { - return tsig; -} - -public void -setTimeout(int secs, int msecs) { - timeoutValue = (long)secs * 1000 + msecs; -} - -public void -setTimeout(int secs) { - setTimeout(secs, 0); -} - -long -getTimeout() { - return timeoutValue; -} - -private Message -parseMessage(byte [] b) throws WireParseException { - try { - return (new Message(b)); - } - catch (IOException e) { - if (Options.check("verbose")) - e.printStackTrace(); - if (!(e instanceof WireParseException)) - e = new WireParseException("Error parsing message"); - throw (WireParseException) e; - } -} - -private void -verifyTSIG(Message query, Message response, byte [] b, TSIG tsig) { - if (tsig == null) - return; - int error = tsig.verify(response, b, query.getTSIG()); - if (Options.check("verbose")) - System.err.println("TSIG verify: " + Rcode.TSIGstring(error)); -} - -private void -applyEDNS(Message query) { - if (queryOPT == null || query.getOPT() != null) - return; - query.addRecord(queryOPT, Section.ADDITIONAL); -} - -private int -maxUDPSize(Message query) { - OPTRecord opt = query.getOPT(); - if (opt == null) - return DEFAULT_UDPSIZE; - else - return opt.getPayloadSize(); -} - -/** - * Sends a message to a single server and waits for a response. No checking - * is done to ensure that the response is associated with the query. - * @param query The query to send. - * @return The response. - * @throws IOException An error occurred while sending or receiving. - */ -public Message -send(Message query) throws IOException { - if (Options.check("verbose")) - System.err.println("Sending to " + - address.getAddress().getHostAddress() + - ":" + address.getPort()); - - if (query.getHeader().getOpcode() == Opcode.QUERY) { - Record question = query.getQuestion(); - if (question != null && question.getType() == Type.AXFR) - return sendAXFR(query); - } - - query = (Message) query.clone(); - applyEDNS(query); - if (tsig != null) - tsig.apply(query, null); - - byte [] out = query.toWire(Message.MAXLENGTH); - int udpSize = maxUDPSize(query); - boolean tcp = false; - long endTime = System.currentTimeMillis() + timeoutValue; - do { - byte [] in; - - if (useTCP || out.length > udpSize) - tcp = true; - if (tcp) - in = TCPClient.sendrecv(localAddress, address, out, - endTime); - else - in = UDPClient.sendrecv(localAddress, address, out, - udpSize, endTime); - - /* - * Check that the response is long enough. - */ - if (in.length < Header.LENGTH) { - throw new WireParseException("invalid DNS header - " + - "too short"); - } - /* - * Check that the response ID matches the query ID. We want - * to check this before actually parsing the message, so that - * if there's a malformed response that's not ours, it - * doesn't confuse us. - */ - int id = ((in[0] & 0xFF) << 8) + (in[1] & 0xFF); - int qid = query.getHeader().getID(); - if (id != qid) { - String error = "invalid message id: expected " + qid + - "; got id " + id; - if (tcp) { - throw new WireParseException(error); - } else { - if (Options.check("verbose")) { - System.err.println(error); - } - continue; - } - } - Message response = parseMessage(in); - verifyTSIG(query, response, in, tsig); - if (!tcp && !ignoreTruncation && - response.getHeader().getFlag(Flags.TC)) - { - tcp = true; - continue; - } - return response; - } while (true); -} - -/** - * Asynchronously sends a message to a single server, registering a listener - * to receive a callback on success or exception. Multiple asynchronous - * lookups can be performed in parallel. Since the callback may be invoked - * before the function returns, external synchronization is necessary. - * @param query The query to send - * @param listener The object containing the callbacks. - * @return An identifier, which is also a parameter in the callback - */ -public Object -sendAsync(final Message query, final ResolverListener listener) { - final Object id; - synchronized (this) { - id = uniqueID++; - } - Record question = query.getQuestion(); - String qname; - if (question != null) - qname = question.getName().toString(); - else - qname = "(none)"; - String name = this.getClass() + ": " + qname; - Thread thread = new ResolveThread(this, query, id, listener); - thread.setName(name); - thread.setDaemon(true); - thread.start(); - return id; -} - -private Message -sendAXFR(Message query) throws IOException { - Name qname = query.getQuestion().getName(); - ZoneTransferIn xfrin = ZoneTransferIn.newAXFR(qname, address, tsig); - xfrin.setTimeout((int)(getTimeout() / 1000)); - xfrin.setLocalAddress(localAddress); - try { - xfrin.run(); - } - catch (ZoneTransferException e) { - throw new WireParseException(e.getMessage()); - } - List records = xfrin.getAXFR(); - Message response = new Message(query.getHeader().getID()); - response.getHeader().setFlag(Flags.AA); - response.getHeader().setFlag(Flags.QR); - response.addRecord(query.getQuestion(), Section.QUESTION); - Iterator it = records.iterator(); - while (it.hasNext()) - response.addRecord((Record)it.next(), Section.ANSWER); - return response; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SingleCompressedNameBase.java b/src/main/java/core/org/xbill/DNS/SingleCompressedNameBase.java deleted file mode 100644 index 790ca1f1..00000000 --- a/src/main/java/core/org/xbill/DNS/SingleCompressedNameBase.java +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Implements common functionality for the many record types whose format - * is a single compressed name. - * - * @author Brian Wellington - */ - -abstract class SingleCompressedNameBase extends SingleNameBase { - -private static final long serialVersionUID = -236435396815460677L; - -protected -SingleCompressedNameBase() {} - -protected -SingleCompressedNameBase(Name name, int type, int dclass, long ttl, - Name singleName, String description) -{ - super(name, type, dclass, ttl, singleName, description); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - singleName.toWire(out, c, canonical); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SingleNameBase.java b/src/main/java/core/org/xbill/DNS/SingleNameBase.java deleted file mode 100644 index 6d6c0415..00000000 --- a/src/main/java/core/org/xbill/DNS/SingleNameBase.java +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * Implements common functionality for the many record types whose format - * is a single name. - * - * @author Brian Wellington - */ - -abstract class SingleNameBase extends Record { - -private static final long serialVersionUID = -18595042501413L; - -protected Name singleName; - -protected -SingleNameBase() {} - -protected -SingleNameBase(Name name, int type, int dclass, long ttl) { - super(name, type, dclass, ttl); -} - -protected -SingleNameBase(Name name, int type, int dclass, long ttl, Name singleName, - String description) -{ - super(name, type, dclass, ttl); - this.singleName = checkName(description, singleName); -} - -void -rrFromWire(DNSInput in) throws IOException { - singleName = new Name(in); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - singleName = st.getName(origin); -} - -String -rrToString() { - return singleName.toString(); -} - -protected Name -getSingleName() { - return singleName; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - singleName.toWire(out, null, canonical); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/SystemResolverConfig.java b/src/main/java/core/org/xbill/DNS/SystemResolverConfig.java deleted file mode 100644 index 9dabec47..00000000 --- a/src/main/java/core/org/xbill/DNS/SystemResolverConfig.java +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.lang.reflect.Method; -import java.util.*; - -public class SystemResolverConfig { - -private String [] servers = null; -private Name [] searchlist = null; -private int ndots = -1; - -public SystemResolverConfig() { - if (servers == null || searchlist == null) { - String OS = System.getProperty("os.name"); - String vendor = System.getProperty("java.vendor"); - if (OS.indexOf("Windows") != -1) { - if (OS.indexOf("95") != -1 || - OS.indexOf("98") != -1 || - OS.indexOf("ME") != -1) - find95(); - else - findNT(); - } else if (OS.indexOf("NetWare") != -1) { - findNetware(); - } else if (vendor.indexOf("Android") != -1) { - findAndroid(); - } else { - findUnix(); - } - } -} - -private void -addServer(String server, List list) { - if (list.contains(server)) - return; - list.add(server); -} - -private void -addSearch(String search, List list) { - Name name; - try { - name = Name.fromString(search, Name.root); - } - catch (TextParseException e) { - return; - } - if (list.contains(name)) - return; - list.add(name); -} - -private int -parseNdots(String token) { - token = token.substring(6); - try { - int ndots = Integer.parseInt(token); - if (ndots >= 0) { - return ndots; - } - } - catch (NumberFormatException e) { - } - return -1; -} - -private void -configureFromLists(List lserver, List lsearch) { - if (servers == null && lserver.size() > 0) - servers = (String []) lserver.toArray(new String[0]); - if (searchlist == null && lsearch.size() > 0) - searchlist = (Name []) lsearch.toArray(new Name[0]); -} - -private void -configureNdots(int lndots) { - if (ndots < 0 && lndots > 0) - ndots = lndots; -} - -/** - * Looks in /etc/resolv.conf to find servers and a search path. - * "nameserver" lines specify servers. "domain" and "search" lines - * define the search path. - */ -private void -findResolvConf(String file) { - InputStream in = null; - try { - in = new FileInputStream(file); - } - catch (FileNotFoundException e) { - return; - } - InputStreamReader isr = new InputStreamReader(in); - BufferedReader br = new BufferedReader(isr); - List lserver = new ArrayList(0); - List lsearch = new ArrayList(0); - int lndots = -1; - try { - String line; - while ((line = br.readLine()) != null) { - if (line.startsWith("nameserver")) { - StringTokenizer st = new StringTokenizer(line); - st.nextToken(); /* skip nameserver */ - addServer(st.nextToken(), lserver); - } - else if (line.startsWith("domain")) { - StringTokenizer st = new StringTokenizer(line); - st.nextToken(); /* skip domain */ - if (!st.hasMoreTokens()) - continue; - if (lsearch.isEmpty()) - addSearch(st.nextToken(), lsearch); - } - else if (line.startsWith("search")) { - if (!lsearch.isEmpty()) - lsearch.clear(); - StringTokenizer st = new StringTokenizer(line); - st.nextToken(); /* skip search */ - while (st.hasMoreTokens()) - addSearch(st.nextToken(), lsearch); - } - else if(line.startsWith("options")) { - StringTokenizer st = new StringTokenizer(line); - st.nextToken(); /* skip options */ - while (st.hasMoreTokens()) { - String token = st.nextToken(); - if (token.startsWith("ndots:")) { - lndots = parseNdots(token); - } - } - } - } - br.close(); - } - catch (IOException e) { - } - - configureFromLists(lserver, lsearch); - configureNdots(lndots); -} - -private void -findUnix() { - findResolvConf("/etc/resolv.conf"); -} - -private void -findNetware() { - findResolvConf("sys:/etc/resolv.cfg"); -} - -/** - * Parses the output of winipcfg or ipconfig. - */ -private void -findWin(InputStream in, Locale locale) { - String packageName = SystemResolverConfig.class.getPackage().getName(); - String resPackageName = packageName + ".windows.DNSServer"; - ResourceBundle res; - if (locale != null) - res = ResourceBundle.getBundle(resPackageName, locale); - else - res = ResourceBundle.getBundle(resPackageName); - - String host_name = res.getString("host_name"); - String primary_dns_suffix = res.getString("primary_dns_suffix"); - String dns_suffix = res.getString("dns_suffix"); - String dns_servers = res.getString("dns_servers"); - - BufferedReader br = new BufferedReader(new InputStreamReader(in)); - try { - List lserver = new ArrayList(); - List lsearch = new ArrayList(); - String line = null; - boolean readingServers = false; - boolean readingSearches = false; - while ((line = br.readLine()) != null) { - StringTokenizer st = new StringTokenizer(line); - if (!st.hasMoreTokens()) { - readingServers = false; - readingSearches = false; - continue; - } - String s = st.nextToken(); - if (line.indexOf(":") != -1) { - readingServers = false; - readingSearches = false; - } - - if (line.indexOf(host_name) != -1) { - while (st.hasMoreTokens()) - s = st.nextToken(); - Name name; - try { - name = Name.fromString(s, null); - } - catch (TextParseException e) { - continue; - } - if (name.labels() == 1) - continue; - addSearch(s, lsearch); - } else if (line.indexOf(primary_dns_suffix) != -1) { - while (st.hasMoreTokens()) - s = st.nextToken(); - if (s.equals(":")) - continue; - addSearch(s, lsearch); - readingSearches = true; - } else if (readingSearches || - line.indexOf(dns_suffix) != -1) - { - while (st.hasMoreTokens()) - s = st.nextToken(); - if (s.equals(":")) - continue; - addSearch(s, lsearch); - readingSearches = true; - } else if (readingServers || - line.indexOf(dns_servers) != -1) - { - while (st.hasMoreTokens()) - s = st.nextToken(); - if (s.equals(":")) - continue; - addServer(s, lserver); - readingServers = true; - } - } - - configureFromLists(lserver, lsearch); - } - catch (IOException e) { - } - return; -} - -private void -findWin(InputStream in) { - String property = "org.xbill.DNS.windows.parse.buffer"; - final int defaultBufSize = 8 * 1024; - int bufSize = Integer.getInteger(property, defaultBufSize).intValue(); - BufferedInputStream b = new BufferedInputStream(in, bufSize); - b.mark(bufSize); - findWin(b, null); - if (servers == null) { - try { - b.reset(); - } - catch (IOException e) { - return; - } - findWin(b, new Locale("", "")); - } -} - -/** - * Calls winipcfg and parses the result to find servers and a search path. - */ -private void -find95() { - String s = "winipcfg.out"; - try { - Process p; - p = Runtime.getRuntime().exec("winipcfg /all /batch " + s); - p.waitFor(); - File f = new File(s); - findWin(new FileInputStream(f)); - new File(s).delete(); - } - catch (Exception e) { - return; - } -} - -/** - * Calls ipconfig and parses the result to find servers and a search path. - */ -private void -findNT() { - try { - Process p; - p = Runtime.getRuntime().exec("ipconfig /all"); - findWin(p.getInputStream()); - p.destroy(); - } - catch (Exception e) { - return; - } -} - -/** - * Parses the output of getprop, which is the only way to get DNS - * info on Android. getprop might disappear in future releases, so - * this code comes with a use-by date. - */ -private void -findAndroid() { - // This originally looked for all lines containing .dns; but - // http://code.google.com/p/android/issues/detail?id=2207#c73 - // indicates that net.dns* should always be the active nameservers, so - // we use those. - final String re1 = "^\\d+(\\.\\d+){3}$"; - final String re2 = "^[0-9a-f]+(:[0-9a-f]*)+:[0-9a-f]+$"; - ArrayList lserver = new ArrayList(); - ArrayList lsearch = new ArrayList(); - try { - Class SystemProperties = - Class.forName("android.os.SystemProperties"); - Method method = - SystemProperties.getMethod("get", - new Class[] { String.class }); - final String [] netdns = new String [] {"net.dns1", "net.dns2", - "net.dns3", "net.dns4"}; - for (int i = 0; i < netdns.length; i++) { - Object [] args = new Object [] { netdns[i] }; - String v = (String) method.invoke(null, args); - if (v != null && - (v.matches(re1) || v.matches(re2)) && - !lserver.contains(v)) - lserver.add(v); - } - } catch ( Exception e ) { - // ignore resolutely - } - configureFromLists(lserver, lsearch); -} - -/** Returns all located servers */ -public String [] -servers() { - return servers; -} - -/** Returns the first located server */ -public String -server() { - if (servers == null) - return null; - return servers[0]; -} - -/** Returns all entries in the located search path */ -public Name [] -searchPath() { - return searchlist; -} - -/** - * Returns the located ndots value, or the default (1) if not configured. - * Note that ndots can only be configured in a resolv.conf file, and will only - * take effect if ResolverConfig uses resolv.conf directly (that is, if the - * JVM does not include the sun.net.dns.ResolverConfiguration class). - */ -public int -ndots() { - if (ndots < 0) - return 1; - return ndots; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/TCPClient.java b/src/main/java/core/org/xbill/DNS/TCPClient.java deleted file mode 100644 index efd8cbe4..00000000 --- a/src/main/java/core/org/xbill/DNS/TCPClient.java +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) 2005 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; - -final class TCPClient extends Client { - -public -TCPClient(long endTime) throws IOException { - super(SocketChannel.open(), endTime); -} - -void -bind(SocketAddress addr) throws IOException { - SocketChannel channel = (SocketChannel) key.channel(); - channel.socket().bind(addr); -} - -void -connect(SocketAddress addr) throws IOException { - SocketChannel channel = (SocketChannel) key.channel(); - if (channel.connect(addr)) - return; - key.interestOps(SelectionKey.OP_CONNECT); - try { - while (!channel.finishConnect()) { - if (!key.isConnectable()) - blockUntil(key, endTime); - } - } - finally { - if (key.isValid()) - key.interestOps(0); - } -} - -void -send(byte [] data) throws IOException { - SocketChannel channel = (SocketChannel) key.channel(); - verboseLog("TCP write", channel.socket().getLocalSocketAddress(), - channel.socket().getRemoteSocketAddress(), data); - byte [] lengthArray = new byte[2]; - lengthArray[0] = (byte)(data.length >>> 8); - lengthArray[1] = (byte)(data.length & 0xFF); - ByteBuffer [] buffers = new ByteBuffer[2]; - buffers[0] = ByteBuffer.wrap(lengthArray); - buffers[1] = ByteBuffer.wrap(data); - int nsent = 0; - key.interestOps(SelectionKey.OP_WRITE); - try { - while (nsent < data.length + 2) { - if (key.isWritable()) { - long n = channel.write(buffers); - if (n < 0) - throw new EOFException(); - nsent += (int) n; - if (nsent < data.length + 2 && - System.currentTimeMillis() > endTime) - throw new SocketTimeoutException(); - } else - blockUntil(key, endTime); - } - } - finally { - if (key.isValid()) - key.interestOps(0); - } -} - -private byte [] -_recv(int length) throws IOException { - SocketChannel channel = (SocketChannel) key.channel(); - int nrecvd = 0; - byte [] data = new byte[length]; - ByteBuffer buffer = ByteBuffer.wrap(data); - key.interestOps(SelectionKey.OP_READ); - try { - while (nrecvd < length) { - if (key.isReadable()) { - long n = channel.read(buffer); - if (n < 0) - throw new EOFException(); - nrecvd += (int) n; - if (nrecvd < length && - System.currentTimeMillis() > endTime) - throw new SocketTimeoutException(); - } else - blockUntil(key, endTime); - } - } - finally { - if (key.isValid()) - key.interestOps(0); - } - return data; -} - -byte [] -recv() throws IOException { - byte [] buf = _recv(2); - int length = ((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF); - byte [] data = _recv(length); - SocketChannel channel = (SocketChannel) key.channel(); - verboseLog("TCP read", channel.socket().getLocalSocketAddress(), - channel.socket().getRemoteSocketAddress(), data); - return data; -} - -static byte [] -sendrecv(SocketAddress local, SocketAddress remote, byte [] data, long endTime) -throws IOException -{ - TCPClient client = new TCPClient(endTime); - try { - if (local != null) - client.bind(local); - client.connect(remote); - client.send(data); - return client.recv(); - } - finally { - client.cleanup(); - } -} - -static byte [] -sendrecv(SocketAddress addr, byte [] data, long endTime) throws IOException { - return sendrecv(null, addr, data, endTime); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/TKEYRecord.java b/src/main/java/core/org/xbill/DNS/TKEYRecord.java deleted file mode 100644 index 4dcbb5c3..00000000 --- a/src/main/java/core/org/xbill/DNS/TKEYRecord.java +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; -import org.xbill.DNS.utils.*; - -/** - * Transaction Key - used to compute and/or securely transport a shared - * secret to be used with TSIG. - * @see TSIG - * - * @author Brian Wellington - */ - -public class TKEYRecord extends Record { - -private static final long serialVersionUID = 8828458121926391756L; - -private Name alg; -private Date timeInception; -private Date timeExpire; -private int mode, error; -private byte [] key; -private byte [] other; - -/** The key is assigned by the server (unimplemented) */ -public static final int SERVERASSIGNED = 1; - -/** The key is computed using a Diffie-Hellman key exchange */ -public static final int DIFFIEHELLMAN = 2; - -/** The key is computed using GSS_API (unimplemented) */ -public static final int GSSAPI = 3; - -/** The key is assigned by the resolver (unimplemented) */ -public static final int RESOLVERASSIGNED = 4; - -/** The key should be deleted */ -public static final int DELETE = 5; - -TKEYRecord() {} - -Record -getObject() { - return new TKEYRecord(); -} - -/** - * Creates a TKEY Record from the given data. - * @param alg The shared key's algorithm - * @param timeInception The beginning of the validity period of the shared - * secret or keying material - * @param timeExpire The end of the validity period of the shared - * secret or keying material - * @param mode The mode of key agreement - * @param error The extended error field. Should be 0 in queries - * @param key The shared secret - * @param other The other data field. Currently unused - * responses. - */ -public -TKEYRecord(Name name, int dclass, long ttl, Name alg, - Date timeInception, Date timeExpire, int mode, int error, - byte [] key, byte other[]) -{ - super(name, Type.TKEY, dclass, ttl); - this.alg = checkName("alg", alg); - this.timeInception = timeInception; - this.timeExpire = timeExpire; - this.mode = checkU16("mode", mode); - this.error = checkU16("error", error); - this.key = key; - this.other = other; -} - -void -rrFromWire(DNSInput in) throws IOException { - alg = new Name(in); - timeInception = new Date(1000 * in.readU32()); - timeExpire = new Date(1000 * in.readU32()); - mode = in.readU16(); - error = in.readU16(); - - int keylen = in.readU16(); - if (keylen > 0) - key = in.readByteArray(keylen); - else - key = null; - - int otherlen = in.readU16(); - if (otherlen > 0) - other = in.readByteArray(otherlen); - else - other = null; -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - throw st.exception("no text format defined for TKEY"); -} - -protected String -modeString() { - switch (mode) { - case SERVERASSIGNED: return "SERVERASSIGNED"; - case DIFFIEHELLMAN: return "DIFFIEHELLMAN"; - case GSSAPI: return "GSSAPI"; - case RESOLVERASSIGNED: return "RESOLVERASSIGNED"; - case DELETE: return "DELETE"; - default: return Integer.toString(mode); - } -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(alg); - sb.append(" "); - if (Options.check("multiline")) - sb.append("(\n\t"); - sb.append(FormattedTime.format(timeInception)); - sb.append(" "); - sb.append(FormattedTime.format(timeExpire)); - sb.append(" "); - sb.append(modeString()); - sb.append(" "); - sb.append(Rcode.TSIGstring(error)); - if (Options.check("multiline")) { - sb.append("\n"); - if (key != null) { - sb.append(base64.formatString(key, 64, "\t", false)); - sb.append("\n"); - } - if (other != null) - sb.append(base64.formatString(other, 64, "\t", false)); - sb.append(" )"); - } else { - sb.append(" "); - if (key != null) { - sb.append(base64.toString(key)); - sb.append(" "); - } - if (other != null) - sb.append(base64.toString(other)); - } - return sb.toString(); -} - -/** Returns the shared key's algorithm */ -public Name -getAlgorithm() { - return alg; -} - -/** - * Returns the beginning of the validity period of the shared secret or - * keying material - */ -public Date -getTimeInception() { - return timeInception; -} - -/** - * Returns the end of the validity period of the shared secret or - * keying material - */ -public Date -getTimeExpire() { - return timeExpire; -} - -/** Returns the key agreement mode */ -public int -getMode() { - return mode; -} - -/** Returns the extended error */ -public int -getError() { - return error; -} - -/** Returns the shared secret or keying material */ -public byte [] -getKey() { - return key; -} - -/** Returns the other data */ -public byte [] -getOther() { - return other; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - alg.toWire(out, null, canonical); - - out.writeU32(timeInception.getTime() / 1000); - out.writeU32(timeExpire.getTime() / 1000); - - out.writeU16(mode); - out.writeU16(error); - - if (key != null) { - out.writeU16(key.length); - out.writeByteArray(key); - } - else - out.writeU16(0); - - if (other != null) { - out.writeU16(other.length); - out.writeByteArray(other); - } - else - out.writeU16(0); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/TLSARecord.java b/src/main/java/core/org/xbill/DNS/TLSARecord.java deleted file mode 100644 index 48e2e80c..00000000 --- a/src/main/java/core/org/xbill/DNS/TLSARecord.java +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import org.xbill.DNS.utils.*; - -/** - * Transport Layer Security Authentication - * - * @author Brian Wellington - */ - -public class TLSARecord extends Record { - -private static final long serialVersionUID = 356494267028580169L; - -public static class CertificateUsage { - private CertificateUsage() {} - - public static final int CA_CONSTRAINT = 0; - public static final int SERVICE_CERTIFICATE_CONSTRAINT = 1; - public static final int TRUST_ANCHOR_ASSERTION = 2; - public static final int DOMAIN_ISSUED_CERTIFICATE = 3; -} - -public static class Selector { - private Selector() {} - - /** - * Full certificate; the Certificate binary structure defined in - * [RFC5280] - */ - public static final int FULL_CERTIFICATE = 0; - - /** - * SubjectPublicKeyInfo; DER-encoded binary structure defined in - * [RFC5280] - */ - public static final int SUBJECT_PUBLIC_KEY_INFO = 1; -} - -public static class MatchingType { - private MatchingType() {} - - /** Exact match on selected content */ - public static final int EXACT = 0; - - /** SHA-256 hash of selected content [RFC6234] */ - public static final int SHA256 = 1; - - /** SHA-512 hash of selected content [RFC6234] */ - public static final int SHA512 = 2; -} - -private int certificateUsage; -private int selector; -private int matchingType; -private byte [] certificateAssociationData; - -TLSARecord() {} - -Record -getObject() { - return new TLSARecord(); -} - -/** - * Creates an TLSA Record from the given data - * @param certificateUsage The provided association that will be used to - * match the certificate presented in the TLS handshake. - * @param selector The part of the TLS certificate presented by the server - * that will be matched against the association data. - * @param matchingType How the certificate association is presented. - * @param certificateAssociationData The "certificate association data" to be - * matched. - */ -public -TLSARecord(Name name, int dclass, long ttl, - int certificateUsage, int selector, int matchingType, - byte [] certificateAssociationData) -{ - super(name, Type.TLSA, dclass, ttl); - this.certificateUsage = checkU8("certificateUsage", certificateUsage); - this.selector = checkU8("selector", selector); - this.matchingType = checkU8("matchingType", matchingType); - this.certificateAssociationData = checkByteArrayLength( - "certificateAssociationData", - certificateAssociationData, - 0xFFFF); -} - -void -rrFromWire(DNSInput in) throws IOException { - certificateUsage = in.readU8(); - selector = in.readU8(); - matchingType = in.readU8(); - certificateAssociationData = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - certificateUsage = st.getUInt8(); - selector = st.getUInt8(); - matchingType = st.getUInt8(); - certificateAssociationData = st.getHex(); -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(certificateUsage); - sb.append(" "); - sb.append(selector); - sb.append(" "); - sb.append(matchingType); - sb.append(" "); - sb.append(base16.toString(certificateAssociationData)); - - return sb.toString(); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU8(certificateUsage); - out.writeU8(selector); - out.writeU8(matchingType); - out.writeByteArray(certificateAssociationData); -} - -/** Returns the certificate usage of the TLSA record */ -public int -getCertificateUsage() { - return certificateUsage; -} - -/** Returns the selector of the TLSA record */ -public int -getSelector() { - return selector; -} - -/** Returns the matching type of the TLSA record */ -public int -getMatchingType() { - return matchingType; -} - -/** Returns the certificate associate data of this TLSA record */ -public final byte [] -getCertificateAssociationData() { - return certificateAssociationData; -} - -} diff --git a/src/main/java/core/org/xbill/DNS/TSIG.java b/src/main/java/core/org/xbill/DNS/TSIG.java deleted file mode 100644 index 509b37bd..00000000 --- a/src/main/java/core/org/xbill/DNS/TSIG.java +++ /dev/null @@ -1,661 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.*; -import java.security.GeneralSecurityException; -import javax.crypto.spec.SecretKeySpec; -import javax.crypto.SecretKey; -import javax.crypto.Mac; -import org.xbill.DNS.utils.base64; - -/** - * Transaction signature handling. This class generates and verifies - * TSIG records on messages, which provide transaction security. - * @see TSIGRecord - * - * @author Brian Wellington - */ - -public class TSIG { - -/** The domain name representing the HMAC-MD5 algorithm. */ -public static final Name HMAC_MD5 = - Name.fromConstantString("HMAC-MD5.SIG-ALG.REG.INT."); - -/** The domain name representing the HMAC-MD5 algorithm (deprecated). */ -public static final Name HMAC = HMAC_MD5; - -/** The domain name representing the HMAC-SHA1 algorithm. */ -public static final Name HMAC_SHA1 = Name.fromConstantString("hmac-sha1."); - -/** - * The domain name representing the HMAC-SHA224 algorithm. - * Note that SHA224 is not supported by Java out-of-the-box, this requires use - * of a third party provider like BouncyCastle.org. - */ -public static final Name HMAC_SHA224 = Name.fromConstantString("hmac-sha224."); - -/** The domain name representing the HMAC-SHA256 algorithm. */ -public static final Name HMAC_SHA256 = Name.fromConstantString("hmac-sha256."); - -/** The domain name representing the HMAC-SHA384 algorithm. */ -public static final Name HMAC_SHA384 = Name.fromConstantString("hmac-sha384."); - -/** The domain name representing the HMAC-SHA512 algorithm. */ -public static final Name HMAC_SHA512 = Name.fromConstantString("hmac-sha512."); - -private static Map algMap; - -static { - Map out = new HashMap(); - out.put(HMAC_MD5, "HmacMD5"); - out.put(HMAC_SHA1, "HmacSHA1"); - out.put(HMAC_SHA224, "HmacSHA224"); - out.put(HMAC_SHA256, "HmacSHA256"); - out.put(HMAC_SHA384, "HmacSHA384"); - out.put(HMAC_SHA512, "HmacSHA512"); - algMap = Collections.unmodifiableMap(out); -} - -public static Name -algorithmToName(String alg) -{ - Iterator it = algMap.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry entry = (Map.Entry) it.next(); - if (alg.equalsIgnoreCase((String)entry.getValue())) - return (Name) entry.getKey(); - } - throw new IllegalArgumentException("Unknown algorithm"); -} -public static String -nameToAlgorithm(Name name) -{ - String alg = (String) algMap.get(name); - if (alg != null) - return alg; - throw new IllegalArgumentException("Unknown algorithm"); -} - -/** - * The default fudge value for outgoing packets. Can be overriden by the - * tsigfudge option. - */ -public static final short FUDGE = 300; - -private Name name, alg; -private Mac hmac; - -/** - * Verifies the data (computes the secure hash and compares it to the input) - * @param mac The HMAC generator - * @param signature The signature to compare against - * @return true if the signature matches, false otherwise - */ -private static boolean -verify(Mac mac, byte [] signature) { - return verify(mac, signature, false); -} - -/** - * Verifies the data (computes the secure hash and compares it to the input) - * @param mac The HMAC generator - * @param signature The signature to compare against - * @param truncation_ok If true, the signature may be truncated; only the - * number of bytes in the provided signature are compared. - * @return true if the signature matches, false otherwise - */ -private static boolean -verify(Mac mac, byte [] signature, boolean truncation_ok) { - byte [] expected = mac.doFinal(); - if (truncation_ok && signature.length < expected.length) { - byte [] truncated = new byte[signature.length]; - System.arraycopy(expected, 0, truncated, 0, truncated.length); - expected = truncated; - } - return Arrays.equals(signature, expected); -} - -private void -init_hmac(String macAlgorithm, SecretKey key) { - try { - hmac = Mac.getInstance(macAlgorithm); - hmac.init(key); - } - catch (GeneralSecurityException ex) { - throw new IllegalArgumentException("Caught security " + - "exception setting up " + - "HMAC."); - } -} - -/** - * Creates a new TSIG key, which can be used to sign or verify a message. - * @param algorithm The algorithm of the shared key. - * @param name The name of the shared key. - * @param keyBytes The shared key's data. - */ -public -TSIG(Name algorithm, Name name, byte [] keyBytes) { - this.name = name; - this.alg = algorithm; - String macAlgorithm = nameToAlgorithm(algorithm); - SecretKey key = new SecretKeySpec(keyBytes, macAlgorithm); - init_hmac(macAlgorithm, key); -} - -/** - * Creates a new TSIG key, which can be used to sign or verify a message. - * @param algorithm The algorithm of the shared key. - * @param name The name of the shared key. - * @param key The shared key. - */ -public -TSIG(Name algorithm, Name name, SecretKey key) { - this.name = name; - this.alg = algorithm; - String macAlgorithm = nameToAlgorithm(algorithm); - init_hmac(macAlgorithm, key); -} - -/** - * Creates a new TSIG key from a pre-initialized Mac instance. - * This assumes that init() has already been called on the mac - * to set up the key. - * @param mac The JCE HMAC object - * @param name The name of the key - */ -public -TSIG(Mac mac, Name name) { - this.name = name; - this.hmac = mac; - this.alg = algorithmToName(mac.getAlgorithm()); -} - -/** - * Creates a new TSIG key with the hmac-md5 algorithm, which can be used to - * sign or verify a message. - * @param name The name of the shared key. - * @param key The shared key's data. - */ -public -TSIG(Name name, byte [] key) { - this(HMAC_MD5, name, key); -} - -/** - * Creates a new TSIG object, which can be used to sign or verify a message. - * @param name The name of the shared key. - * @param key The shared key's data represented as a base64 encoded string. - * @throws IllegalArgumentException The key name is an invalid name - * @throws IllegalArgumentException The key data is improperly encoded - */ -public -TSIG(Name algorithm, String name, String key) { - byte[] keyBytes = base64.fromString(key); - if (keyBytes == null) - throw new IllegalArgumentException("Invalid TSIG key string"); - try { - this.name = Name.fromString(name, Name.root); - } - catch (TextParseException e) { - throw new IllegalArgumentException("Invalid TSIG key name"); - } - this.alg = algorithm; - String macAlgorithm = nameToAlgorithm(this.alg); - init_hmac(macAlgorithm, new SecretKeySpec(keyBytes, macAlgorithm)); -} - -/** - * Creates a new TSIG object, which can be used to sign or verify a message. - * @param name The name of the shared key. - * @param algorithm The algorithm of the shared key. The legal values are - * "hmac-md5", "hmac-sha1", "hmac-sha224", "hmac-sha256", "hmac-sha384", and - * "hmac-sha512". - * @param key The shared key's data represented as a base64 encoded string. - * @throws IllegalArgumentException The key name is an invalid name - * @throws IllegalArgumentException The key data is improperly encoded - */ -public -TSIG(String algorithm, String name, String key) { - this(algorithmToName(algorithm), name, key); -} - -/** - * Creates a new TSIG object with the hmac-md5 algorithm, which can be used to - * sign or verify a message. - * @param name The name of the shared key - * @param key The shared key's data, represented as a base64 encoded string. - * @throws IllegalArgumentException The key name is an invalid name - * @throws IllegalArgumentException The key data is improperly encoded - */ -public -TSIG(String name, String key) { - this(HMAC_MD5, name, key); -} - -/** - * Creates a new TSIG object, which can be used to sign or verify a message. - * @param str The TSIG key, in the form name:secret, name/secret, - * alg:name:secret, or alg/name/secret. If an algorithm is specified, it must - * be "hmac-md5", "hmac-sha1", or "hmac-sha256". - * @throws IllegalArgumentException The string does not contain both a name - * and secret. - * @throws IllegalArgumentException The key name is an invalid name - * @throws IllegalArgumentException The key data is improperly encoded - */ -static public TSIG -fromString(String str) { - String [] parts = str.split("[:/]", 3); - if (parts.length < 2) - throw new IllegalArgumentException("Invalid TSIG key " + - "specification"); - if (parts.length == 3) { - try { - return new TSIG(parts[0], parts[1], parts[2]); - } catch (IllegalArgumentException e) { - parts = str.split("[:/]", 2); - } - } - return new TSIG(HMAC_MD5, parts[0], parts[1]); -} - -/** - * Generates a TSIG record with a specific error for a message that has - * been rendered. - * @param m The message - * @param b The rendered message - * @param error The error - * @param old If this message is a response, the TSIG from the request - * @return The TSIG record to be added to the message - */ -public TSIGRecord -generate(Message m, byte [] b, int error, TSIGRecord old) { - Date timeSigned; - if (error != Rcode.BADTIME) - timeSigned = new Date(); - else - timeSigned = old.getTimeSigned(); - int fudge; - boolean signing = false; - if (error == Rcode.NOERROR || error == Rcode.BADTIME) { - signing = true; - hmac.reset(); - } - - fudge = Options.intValue("tsigfudge"); - if (fudge < 0 || fudge > 0x7FFF) - fudge = FUDGE; - - if (old != null) { - DNSOutput out = new DNSOutput(); - out.writeU16(old.getSignature().length); - if (signing) { - hmac.update(out.toByteArray()); - hmac.update(old.getSignature()); - } - } - - /* Digest the message */ - if (signing) - hmac.update(b); - - DNSOutput out = new DNSOutput(); - name.toWireCanonical(out); - out.writeU16(DClass.ANY); /* class */ - out.writeU32(0); /* ttl */ - alg.toWireCanonical(out); - long time = timeSigned.getTime() / 1000; - int timeHigh = (int) (time >> 32); - long timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - out.writeU16(fudge); - - out.writeU16(error); - out.writeU16(0); /* No other data */ - - if (signing) - hmac.update(out.toByteArray()); - - byte [] signature; - if (signing) - signature = hmac.doFinal(); - else - signature = new byte[0]; - - byte [] other = null; - if (error == Rcode.BADTIME) { - out = new DNSOutput(); - time = new Date().getTime() / 1000; - timeHigh = (int) (time >> 32); - timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - other = out.toByteArray(); - } - - return (new TSIGRecord(name, DClass.ANY, 0, alg, timeSigned, fudge, - signature, m.getHeader().getID(), error, other)); -} - -/** - * Generates a TSIG record with a specific error for a message and adds it - * to the message. - * @param m The message - * @param error The error - * @param old If this message is a response, the TSIG from the request - */ -public void -apply(Message m, int error, TSIGRecord old) { - Record r = generate(m, m.toWire(), error, old); - m.addRecord(r, Section.ADDITIONAL); - m.tsigState = Message.TSIG_SIGNED; -} - -/** - * Generates a TSIG record for a message and adds it to the message - * @param m The message - * @param old If this message is a response, the TSIG from the request - */ -public void -apply(Message m, TSIGRecord old) { - apply(m, Rcode.NOERROR, old); -} - -/** - * Generates a TSIG record for a message and adds it to the message - * @param m The message - * @param old If this message is a response, the TSIG from the request - */ -public void -applyStream(Message m, TSIGRecord old, boolean first) { - if (first) { - apply(m, old); - return; - } - Date timeSigned = new Date(); - int fudge; - hmac.reset(); - - fudge = Options.intValue("tsigfudge"); - if (fudge < 0 || fudge > 0x7FFF) - fudge = FUDGE; - - DNSOutput out = new DNSOutput(); - out.writeU16(old.getSignature().length); - hmac.update(out.toByteArray()); - hmac.update(old.getSignature()); - - /* Digest the message */ - hmac.update(m.toWire()); - - out = new DNSOutput(); - long time = timeSigned.getTime() / 1000; - int timeHigh = (int) (time >> 32); - long timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - out.writeU16(fudge); - - hmac.update(out.toByteArray()); - - byte [] signature = hmac.doFinal(); - byte [] other = null; - - Record r = new TSIGRecord(name, DClass.ANY, 0, alg, timeSigned, fudge, - signature, m.getHeader().getID(), - Rcode.NOERROR, other); - m.addRecord(r, Section.ADDITIONAL); - m.tsigState = Message.TSIG_SIGNED; -} - -/** - * Verifies a TSIG record on an incoming message. Since this is only called - * in the context where a TSIG is expected to be present, it is an error - * if one is not present. After calling this routine, Message.isVerified() may - * be called on this message. - * @param m The message - * @param b An array containing the message in unparsed form. This is - * necessary since TSIG signs the message in wire format, and we can't - * recreate the exact wire format (with the same name compression). - * @param length The length of the message in the array. - * @param old If this message is a response, the TSIG from the request - * @return The result of the verification (as an Rcode) - * @see Rcode - */ -public byte -verify(Message m, byte [] b, int length, TSIGRecord old) { - m.tsigState = Message.TSIG_FAILED; - TSIGRecord tsig = m.getTSIG(); - hmac.reset(); - if (tsig == null) - return Rcode.FORMERR; - - if (!tsig.getName().equals(name) || !tsig.getAlgorithm().equals(alg)) { - if (Options.check("verbose")) - System.err.println("BADKEY failure"); - return Rcode.BADKEY; - } - long now = System.currentTimeMillis(); - long then = tsig.getTimeSigned().getTime(); - long fudge = tsig.getFudge(); - if (Math.abs(now - then) > fudge * 1000) { - if (Options.check("verbose")) - System.err.println("BADTIME failure"); - return Rcode.BADTIME; - } - - if (old != null && tsig.getError() != Rcode.BADKEY && - tsig.getError() != Rcode.BADSIG) - { - DNSOutput out = new DNSOutput(); - out.writeU16(old.getSignature().length); - hmac.update(out.toByteArray()); - hmac.update(old.getSignature()); - } - m.getHeader().decCount(Section.ADDITIONAL); - byte [] header = m.getHeader().toWire(); - m.getHeader().incCount(Section.ADDITIONAL); - hmac.update(header); - - int len = m.tsigstart - header.length; - hmac.update(b, header.length, len); - - DNSOutput out = new DNSOutput(); - tsig.getName().toWireCanonical(out); - out.writeU16(tsig.dclass); - out.writeU32(tsig.ttl); - tsig.getAlgorithm().toWireCanonical(out); - long time = tsig.getTimeSigned().getTime() / 1000; - int timeHigh = (int) (time >> 32); - long timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - out.writeU16(tsig.getFudge()); - out.writeU16(tsig.getError()); - if (tsig.getOther() != null) { - out.writeU16(tsig.getOther().length); - out.writeByteArray(tsig.getOther()); - } else { - out.writeU16(0); - } - - hmac.update(out.toByteArray()); - - byte [] signature = tsig.getSignature(); - int digestLength = hmac.getMacLength(); - int minDigestLength; - if (hmac.getAlgorithm().toLowerCase().contains("md5")) - minDigestLength = 10; - else - minDigestLength = digestLength / 2; - - if (signature.length > digestLength) { - if (Options.check("verbose")) - System.err.println("BADSIG: signature too long"); - return Rcode.BADSIG; - } else if (signature.length < minDigestLength) { - if (Options.check("verbose")) - System.err.println("BADSIG: signature too short"); - return Rcode.BADSIG; - } else if (!verify(hmac, signature, true)) { - if (Options.check("verbose")) - System.err.println("BADSIG: signature verification"); - return Rcode.BADSIG; - } - - m.tsigState = Message.TSIG_VERIFIED; - return Rcode.NOERROR; -} - -/** - * Verifies a TSIG record on an incoming message. Since this is only called - * in the context where a TSIG is expected to be present, it is an error - * if one is not present. After calling this routine, Message.isVerified() may - * be called on this message. - * @param m The message - * @param b The message in unparsed form. This is necessary since TSIG - * signs the message in wire format, and we can't recreate the exact wire - * format (with the same name compression). - * @param old If this message is a response, the TSIG from the request - * @return The result of the verification (as an Rcode) - * @see Rcode - */ -public int -verify(Message m, byte [] b, TSIGRecord old) { - return verify(m, b, b.length, old); -} - -/** - * Returns the maximum length of a TSIG record generated by this key. - * @see TSIGRecord - */ -public int -recordLength() { - return (name.length() + 10 + - alg.length() + - 8 + // time signed, fudge - 18 + // 2 byte MAC length, 16 byte MAC - 4 + // original id, error - 8); // 2 byte error length, 6 byte max error field. -} - -public static class StreamVerifier { - /** - * A helper class for verifying multiple message responses. - */ - - private TSIG key; - private Mac verifier; - private int nresponses; - private int lastsigned; - private TSIGRecord lastTSIG; - - /** Creates an object to verify a multiple message response */ - public - StreamVerifier(TSIG tsig, TSIGRecord old) { - key = tsig; - verifier = tsig.hmac; - nresponses = 0; - lastTSIG = old; - } - - /** - * Verifies a TSIG record on an incoming message that is part of a - * multiple message response. - * TSIG records must be present on the first and last messages, and - * at least every 100 records in between. - * After calling this routine, Message.isVerified() may be called on - * this message. - * @param m The message - * @param b The message in unparsed form - * @return The result of the verification (as an Rcode) - * @see Rcode - */ - public int - verify(Message m, byte [] b) { - TSIGRecord tsig = m.getTSIG(); - - nresponses++; - - if (nresponses == 1) { - int result = key.verify(m, b, lastTSIG); - if (result == Rcode.NOERROR) { - byte [] signature = tsig.getSignature(); - DNSOutput out = new DNSOutput(); - out.writeU16(signature.length); - verifier.update(out.toByteArray()); - verifier.update(signature); - } - lastTSIG = tsig; - return result; - } - - if (tsig != null) - m.getHeader().decCount(Section.ADDITIONAL); - byte [] header = m.getHeader().toWire(); - if (tsig != null) - m.getHeader().incCount(Section.ADDITIONAL); - verifier.update(header); - - int len; - if (tsig == null) - len = b.length - header.length; - else - len = m.tsigstart - header.length; - verifier.update(b, header.length, len); - - if (tsig != null) { - lastsigned = nresponses; - lastTSIG = tsig; - } - else { - boolean required = (nresponses - lastsigned >= 100); - if (required) { - m.tsigState = Message.TSIG_FAILED; - return Rcode.FORMERR; - } else { - m.tsigState = Message.TSIG_INTERMEDIATE; - return Rcode.NOERROR; - } - } - - if (!tsig.getName().equals(key.name) || - !tsig.getAlgorithm().equals(key.alg)) - { - if (Options.check("verbose")) - System.err.println("BADKEY failure"); - m.tsigState = Message.TSIG_FAILED; - return Rcode.BADKEY; - } - - DNSOutput out = new DNSOutput(); - long time = tsig.getTimeSigned().getTime() / 1000; - int timeHigh = (int) (time >> 32); - long timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - out.writeU16(tsig.getFudge()); - verifier.update(out.toByteArray()); - - if (TSIG.verify(verifier, tsig.getSignature()) == false) { - if (Options.check("verbose")) - System.err.println("BADSIG failure"); - m.tsigState = Message.TSIG_FAILED; - return Rcode.BADSIG; - } - - verifier.reset(); - out = new DNSOutput(); - out.writeU16(tsig.getSignature().length); - verifier.update(out.toByteArray()); - verifier.update(tsig.getSignature()); - - m.tsigState = Message.TSIG_VERIFIED; - return Rcode.NOERROR; - } -} - -} diff --git a/src/main/java/core/org/xbill/DNS/TSIGRecord.java b/src/main/java/core/org/xbill/DNS/TSIGRecord.java deleted file mode 100644 index c7ce9ed3..00000000 --- a/src/main/java/core/org/xbill/DNS/TSIGRecord.java +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; -import org.xbill.DNS.utils.*; - -/** - * Transaction Signature - this record is automatically generated by the - * resolver. TSIG records provide transaction security between the - * sender and receiver of a message, using a shared key. - * @see Resolver - * @see TSIG - * - * @author Brian Wellington - */ - -public class TSIGRecord extends Record { - -private static final long serialVersionUID = -88820909016649306L; - -private Name alg; -private Date timeSigned; -private int fudge; -private byte [] signature; -private int originalID; -private int error; -private byte [] other; - -TSIGRecord() {} - -Record -getObject() { - return new TSIGRecord(); -} - -/** - * Creates a TSIG Record from the given data. This is normally called by - * the TSIG class - * @param alg The shared key's algorithm - * @param timeSigned The time that this record was generated - * @param fudge The fudge factor for time - if the time that the message is - * received is not in the range [now - fudge, now + fudge], the signature - * fails - * @param signature The signature - * @param originalID The message ID at the time of its generation - * @param error The extended error field. Should be 0 in queries. - * @param other The other data field. Currently used only in BADTIME - * responses. - * @see TSIG - */ -public -TSIGRecord(Name name, int dclass, long ttl, Name alg, Date timeSigned, - int fudge, byte [] signature, int originalID, int error, - byte other[]) -{ - super(name, Type.TSIG, dclass, ttl); - this.alg = checkName("alg", alg); - this.timeSigned = timeSigned; - this.fudge = checkU16("fudge", fudge); - this.signature = signature; - this.originalID = checkU16("originalID", originalID); - this.error = checkU16("error", error); - this.other = other; -} - -void -rrFromWire(DNSInput in) throws IOException { - alg = new Name(in); - - long timeHigh = in.readU16(); - long timeLow = in.readU32(); - long time = (timeHigh << 32) + timeLow; - timeSigned = new Date(time * 1000); - fudge = in.readU16(); - - int sigLen = in.readU16(); - signature = in.readByteArray(sigLen); - - originalID = in.readU16(); - error = in.readU16(); - - int otherLen = in.readU16(); - if (otherLen > 0) - other = in.readByteArray(otherLen); - else - other = null; -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - throw st.exception("no text format defined for TSIG"); -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(alg); - sb.append(" "); - if (Options.check("multiline")) - sb.append("(\n\t"); - - sb.append (timeSigned.getTime() / 1000); - sb.append (" "); - sb.append (fudge); - sb.append (" "); - sb.append (signature.length); - if (Options.check("multiline")) { - sb.append ("\n"); - sb.append (base64.formatString(signature, 64, "\t", false)); - } else { - sb.append (" "); - sb.append (base64.toString(signature)); - } - sb.append (" "); - sb.append (Rcode.TSIGstring(error)); - sb.append (" "); - if (other == null) - sb.append (0); - else { - sb.append (other.length); - if (Options.check("multiline")) - sb.append("\n\n\n\t"); - else - sb.append(" "); - if (error == Rcode.BADTIME) { - if (other.length != 6) { - sb.append(""); - } else { - long time = ((long)(other[0] & 0xFF) << 40) + - ((long)(other[1] & 0xFF) << 32) + - ((other[2] & 0xFF) << 24) + - ((other[3] & 0xFF) << 16) + - ((other[4] & 0xFF) << 8) + - ((other[5] & 0xFF) ); - sb.append(""); - } - } else { - sb.append("<"); - sb.append(base64.toString(other)); - sb.append(">"); - } - } - if (Options.check("multiline")) - sb.append(" )"); - return sb.toString(); -} - -/** Returns the shared key's algorithm */ -public Name -getAlgorithm() { - return alg; -} - -/** Returns the time that this record was generated */ -public Date -getTimeSigned() { - return timeSigned; -} - -/** Returns the time fudge factor */ -public int -getFudge() { - return fudge; -} - -/** Returns the signature */ -public byte [] -getSignature() { - return signature; -} - -/** Returns the original message ID */ -public int -getOriginalID() { - return originalID; -} - -/** Returns the extended error */ -public int -getError() { - return error; -} - -/** Returns the other data */ -public byte [] -getOther() { - return other; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - alg.toWire(out, null, canonical); - - long time = timeSigned.getTime() / 1000; - int timeHigh = (int) (time >> 32); - long timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - out.writeU16(fudge); - - out.writeU16(signature.length); - out.writeByteArray(signature); - - out.writeU16(originalID); - out.writeU16(error); - - if (other != null) { - out.writeU16(other.length); - out.writeByteArray(other); - } - else - out.writeU16(0); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/TTL.java b/src/main/java/core/org/xbill/DNS/TTL.java deleted file mode 100644 index 01bf4168..00000000 --- a/src/main/java/core/org/xbill/DNS/TTL.java +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Routines for parsing BIND-style TTL values. These values consist of - * numbers followed by 1 letter units of time (W - week, D - day, H - hour, - * M - minute, S - second). - * - * @author Brian Wellington - */ - -public final class TTL { - -public static final long MAX_VALUE = 0x7FFFFFFFL; - -private -TTL() {} - -static void -check(long i) { - if (i < 0 || i > MAX_VALUE) - throw new InvalidTTLException(i); -} - -/** - * Parses a TTL-like value, which can either be expressed as a number or a - * BIND-style string with numbers and units. - * @param s The string representing the numeric value. - * @param clamp Whether to clamp values in the range [MAX_VALUE + 1, 2^32 -1] - * to MAX_VALUE. This should be donw for TTLs, but not other values which - * can be expressed in this format. - * @return The value as a number of seconds - * @throws NumberFormatException The string was not in a valid TTL format. - */ -public static long -parse(String s, boolean clamp) { - if (s == null || s.length() == 0 || !Character.isDigit(s.charAt(0))) - throw new NumberFormatException(); - long value = 0; - long ttl = 0; - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - long oldvalue = value; - if (Character.isDigit(c)) { - value = (value * 10) + Character.getNumericValue(c); - if (value < oldvalue) - throw new NumberFormatException(); - } else { - switch (Character.toUpperCase(c)) { - case 'W': value *= 7; - case 'D': value *= 24; - case 'H': value *= 60; - case 'M': value *= 60; - case 'S': break; - default: throw new NumberFormatException(); - } - ttl += value; - value = 0; - if (ttl > 0xFFFFFFFFL) - throw new NumberFormatException(); - } - } - if (ttl == 0) - ttl = value; - - if (ttl > 0xFFFFFFFFL) - throw new NumberFormatException(); - else if (ttl > MAX_VALUE && clamp) - ttl = MAX_VALUE; - return ttl; -} - -/** - * Parses a TTL, which can either be expressed as a number or a BIND-style - * string with numbers and units. - * @param s The string representing the TTL - * @return The TTL as a number of seconds - * @throws NumberFormatException The string was not in a valid TTL format. - */ -public static long -parseTTL(String s) { - return parse(s, true); -} - -public static String -format(long ttl) { - TTL.check(ttl); - StringBuffer sb = new StringBuffer(); - long secs, mins, hours, days, weeks; - secs = ttl % 60; - ttl /= 60; - mins = ttl % 60; - ttl /= 60; - hours = ttl % 24; - ttl /= 24; - days = ttl % 7; - ttl /= 7; - weeks = ttl; - if (weeks > 0) - sb.append(weeks + "W"); - if (days > 0) - sb.append(days + "D"); - if (hours > 0) - sb.append(hours + "H"); - if (mins > 0) - sb.append(mins + "M"); - if (secs > 0 || (weeks == 0 && days == 0 && hours == 0 && mins == 0)) - sb.append(secs + "S"); - return sb.toString(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/TXTBase.java b/src/main/java/core/org/xbill/DNS/TXTBase.java deleted file mode 100644 index fd99bfb5..00000000 --- a/src/main/java/core/org/xbill/DNS/TXTBase.java +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; - -/** - * Implements common functionality for the many record types whose format - * is a list of strings. - * - * @author Brian Wellington - */ - -abstract class TXTBase extends Record { - -private static final long serialVersionUID = -4319510507246305931L; - -protected List strings; - -protected -TXTBase() {} - -protected -TXTBase(Name name, int type, int dclass, long ttl) { - super(name, type, dclass, ttl); -} - -protected -TXTBase(Name name, int type, int dclass, long ttl, List strings) { - super(name, type, dclass, ttl); - if (strings == null) - throw new IllegalArgumentException("strings must not be null"); - this.strings = new ArrayList(strings.size()); - Iterator it = strings.iterator(); - try { - while (it.hasNext()) { - String s = (String) it.next(); - this.strings.add(byteArrayFromString(s)); - } - } - catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } -} - -protected -TXTBase(Name name, int type, int dclass, long ttl, String string) { - this(name, type, dclass, ttl, Collections.singletonList(string)); -} - -void -rrFromWire(DNSInput in) throws IOException { - strings = new ArrayList(2); - while (in.remaining() > 0) { - byte [] b = in.readCountedString(); - strings.add(b); - } -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - strings = new ArrayList(2); - while (true) { - Tokenizer.Token t = st.get(); - if (!t.isString()) - break; - try { - strings.add(byteArrayFromString(t.value)); - } - catch (TextParseException e) { - throw st.exception(e.getMessage()); - } - - } - st.unget(); -} - -/** converts to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - Iterator it = strings.iterator(); - while (it.hasNext()) { - byte [] array = (byte []) it.next(); - sb.append(byteArrayToString(array, true)); - if (it.hasNext()) - sb.append(" "); - } - return sb.toString(); -} - -/** - * Returns the text strings - * @return A list of Strings corresponding to the text strings. - */ -public List -getStrings() { - List list = new ArrayList(strings.size()); - for (int i = 0; i < strings.size(); i++) - list.add(byteArrayToString((byte []) strings.get(i), false)); - return list; -} - -/** - * Returns the text strings - * @return A list of byte arrays corresponding to the text strings. - */ -public List -getStringsAsByteArrays() { - return strings; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - Iterator it = strings.iterator(); - while (it.hasNext()) { - byte [] b = (byte []) it.next(); - out.writeCountedString(b); - } -} - -} diff --git a/src/main/java/core/org/xbill/DNS/TXTRecord.java b/src/main/java/core/org/xbill/DNS/TXTRecord.java deleted file mode 100644 index ea5de049..00000000 --- a/src/main/java/core/org/xbill/DNS/TXTRecord.java +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.*; - -/** - * Text - stores text strings - * - * @author Brian Wellington - */ - -public class TXTRecord extends TXTBase { - -private static final long serialVersionUID = -5780785764284221342L; - -TXTRecord() {} - -Record -getObject() { - return new TXTRecord(); -} - -/** - * Creates a TXT Record from the given data - * @param strings The text strings - * @throws IllegalArgumentException One of the strings has invalid escapes - */ -public -TXTRecord(Name name, int dclass, long ttl, List strings) { - super(name, Type.TXT, dclass, ttl, strings); -} - -/** - * Creates a TXT Record from the given data - * @param string One text string - * @throws IllegalArgumentException The string has invalid escapes - */ -public -TXTRecord(Name name, int dclass, long ttl, String string) { - super(name, Type.TXT, dclass, ttl, string); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/TextParseException.java b/src/main/java/core/org/xbill/DNS/TextParseException.java deleted file mode 100644 index 3b9a4259..00000000 --- a/src/main/java/core/org/xbill/DNS/TextParseException.java +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2002-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * An exception thrown when unable to parse text. - * - * @author Brian Wellington - */ - -public class TextParseException extends IOException { - -public -TextParseException() { - super(); -} - -public -TextParseException(String s) { - super(s); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Tokenizer.java b/src/main/java/core/org/xbill/DNS/Tokenizer.java deleted file mode 100644 index 9328eb88..00000000 --- a/src/main/java/core/org/xbill/DNS/Tokenizer.java +++ /dev/null @@ -1,732 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) -// -// Copyright (C) 2003-2004 Nominum, Inc. -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR ANY -// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -// OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// - -package org.xbill.DNS; - -import java.io.*; -import java.net.*; - -import org.xbill.DNS.utils.*; - -/** - * Tokenizer is used to parse DNS records and zones from text format, - * - * @author Brian Wellington - * @author Bob Halley - */ - -public class Tokenizer { - -private static String delim = " \t\n;()\""; -private static String quotes = "\""; - -/** End of file */ -public static final int EOF = 0; - -/** End of line */ -public static final int EOL = 1; - -/** Whitespace; only returned when wantWhitespace is set */ -public static final int WHITESPACE = 2; - -/** An identifier (unquoted string) */ -public static final int IDENTIFIER = 3; - -/** A quoted string */ -public static final int QUOTED_STRING = 4; - -/** A comment; only returned when wantComment is set */ -public static final int COMMENT = 5; - -private PushbackInputStream is; -private boolean ungottenToken; -private int multiline; -private boolean quoting; -private String delimiters; -private Token current; -private StringBuffer sb; -private boolean wantClose; - -private String filename; -private int line; - -public static class Token { - /** The type of token. */ - public int type; - - /** The value of the token, or null for tokens without values. */ - public String value; - - private - Token() { - type = -1; - value = null; - } - - private Token - set(int type, StringBuffer value) { - if (type < 0) - throw new IllegalArgumentException(); - this.type = type; - this.value = value == null ? null : value.toString(); - return this; - } - - /** - * Converts the token to a string containing a representation useful - * for debugging. - */ - public String - toString() { - switch (type) { - case EOF: - return ""; - case EOL: - return ""; - case WHITESPACE: - return ""; - case IDENTIFIER: - return ""; - case QUOTED_STRING: - return ""; - case COMMENT: - return ""; - default: - return ""; - } - } - - /** Indicates whether this token contains a string. */ - public boolean - isString() { - return (type == IDENTIFIER || type == QUOTED_STRING); - } - - /** Indicates whether this token contains an EOL or EOF. */ - public boolean - isEOL() { - return (type == EOL || type == EOF); - } -} - -static class TokenizerException extends TextParseException { - String message; - - public - TokenizerException(String filename, int line, String message) { - super(filename + ":" + line + ": " + message); - this.message = message; - } - - public String - getBaseMessage() { - return message; - } -} - -/** - * Creates a Tokenizer from an arbitrary input stream. - * @param is The InputStream to tokenize. - */ -public -Tokenizer(InputStream is) { - if (!(is instanceof BufferedInputStream)) - is = new BufferedInputStream(is); - this.is = new PushbackInputStream(is, 2); - ungottenToken = false; - multiline = 0; - quoting = false; - delimiters = delim; - current = new Token(); - sb = new StringBuffer(); - filename = ""; - line = 1; -} - -/** - * Creates a Tokenizer from a string. - * @param s The String to tokenize. - */ -public -Tokenizer(String s) { - this(new ByteArrayInputStream(s.getBytes())); -} - -/** - * Creates a Tokenizer from a file. - * @param f The File to tokenize. - */ -public -Tokenizer(File f) throws FileNotFoundException { - this(new FileInputStream(f)); - wantClose = true; - filename = f.getName(); -} - -private int -getChar() throws IOException { - int c = is.read(); - if (c == '\r') { - int next = is.read(); - if (next != '\n') - is.unread(next); - c = '\n'; - } - if (c == '\n') - line++; - return c; -} - -private void -ungetChar(int c) throws IOException { - if (c == -1) - return; - is.unread(c); - if (c == '\n') - line--; -} - -private int -skipWhitespace() throws IOException { - int skipped = 0; - while (true) { - int c = getChar(); - if (c != ' ' && c != '\t') { - if (!(c == '\n' && multiline > 0)) { - ungetChar(c); - return skipped; - } - } - skipped++; - } -} - -private void -checkUnbalancedParens() throws TextParseException { - if (multiline > 0) - throw exception("unbalanced parentheses"); -} - -/** - * Gets the next token from a tokenizer. - * @param wantWhitespace If true, leading whitespace will be returned as a - * token. - * @param wantComment If true, comments are returned as tokens. - * @return The next token in the stream. - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ -public Token -get(boolean wantWhitespace, boolean wantComment) throws IOException { - int type; - int c; - - if (ungottenToken) { - ungottenToken = false; - if (current.type == WHITESPACE) { - if (wantWhitespace) - return current; - } else if (current.type == COMMENT) { - if (wantComment) - return current; - } else { - if (current.type == EOL) - line++; - return current; - } - } - int skipped = skipWhitespace(); - if (skipped > 0 && wantWhitespace) - return current.set(WHITESPACE, null); - type = IDENTIFIER; - sb.setLength(0); - while (true) { - c = getChar(); - if (c == -1 || delimiters.indexOf(c) != -1) { - if (c == -1) { - if (quoting) - throw exception("EOF in " + - "quoted string"); - else if (sb.length() == 0) - return current.set(EOF, null); - else - return current.set(type, sb); - } - if (sb.length() == 0 && type != QUOTED_STRING) { - if (c == '(') { - multiline++; - skipWhitespace(); - continue; - } else if (c == ')') { - if (multiline <= 0) - throw exception("invalid " + - "close " + - "parenthesis"); - multiline--; - skipWhitespace(); - continue; - } else if (c == '"') { - if (!quoting) { - quoting = true; - delimiters = quotes; - type = QUOTED_STRING; - } else { - quoting = false; - delimiters = delim; - skipWhitespace(); - } - continue; - } else if (c == '\n') { - return current.set(EOL, null); - } else if (c == ';') { - while (true) { - c = getChar(); - if (c == '\n' || c == -1) - break; - sb.append((char)c); - } - if (wantComment) { - ungetChar(c); - return current.set(COMMENT, sb); - } else if (c == -1 && - type != QUOTED_STRING) - { - checkUnbalancedParens(); - return current.set(EOF, null); - } else if (multiline > 0) { - skipWhitespace(); - sb.setLength(0); - continue; - } else - return current.set(EOL, null); - } else - throw new IllegalStateException(); - } else - ungetChar(c); - break; - } else if (c == '\\') { - c = getChar(); - if (c == -1) - throw exception("unterminated escape sequence"); - sb.append('\\'); - } else if (quoting && c == '\n') { - throw exception("newline in quoted string"); - } - sb.append((char)c); - } - if (sb.length() == 0 && type != QUOTED_STRING) { - checkUnbalancedParens(); - return current.set(EOF, null); - } - return current.set(type, sb); -} - -/** - * Gets the next token from a tokenizer, ignoring whitespace and comments. - * @return The next token in the stream. - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ -public Token -get() throws IOException { - return get(false, false); -} - -/** - * Returns a token to the stream, so that it will be returned by the next call - * to get(). - * @throws IllegalStateException There are already ungotten tokens. - */ -public void -unget() { - if (ungottenToken) - throw new IllegalStateException - ("Cannot unget multiple tokens"); - if (current.type == EOL) - line--; - ungottenToken = true; -} - -/** - * Gets the next token from a tokenizer and converts it to a string. - * @return The next token in the stream, as a string. - * @throws TextParseException The input was invalid or not a string. - * @throws IOException An I/O error occurred. - */ -public String -getString() throws IOException { - Token next = get(); - if (!next.isString()) { - throw exception("expected a string"); - } - return next.value; -} - -private String -_getIdentifier(String expected) throws IOException { - Token next = get(); - if (next.type != IDENTIFIER) - throw exception("expected " + expected); - return next.value; -} - -/** - * Gets the next token from a tokenizer, ensures it is an unquoted string, - * and converts it to a string. - * @return The next token in the stream, as a string. - * @throws TextParseException The input was invalid or not an unquoted string. - * @throws IOException An I/O error occurred. - */ -public String -getIdentifier() throws IOException { - return _getIdentifier("an identifier"); -} - -/** - * Gets the next token from a tokenizer and converts it to a long. - * @return The next token in the stream, as a long. - * @throws TextParseException The input was invalid or not a long. - * @throws IOException An I/O error occurred. - */ -public long -getLong() throws IOException { - String next = _getIdentifier("an integer"); - if (!Character.isDigit(next.charAt(0))) - throw exception("expected an integer"); - try { - return Long.parseLong(next); - } catch (NumberFormatException e) { - throw exception("expected an integer"); - } -} - -/** - * Gets the next token from a tokenizer and converts it to an unsigned 32 bit - * integer. - * @return The next token in the stream, as an unsigned 32 bit integer. - * @throws TextParseException The input was invalid or not an unsigned 32 - * bit integer. - * @throws IOException An I/O error occurred. - */ -public long -getUInt32() throws IOException { - long l = getLong(); - if (l < 0 || l > 0xFFFFFFFFL) - throw exception("expected an 32 bit unsigned integer"); - return l; -} - -/** - * Gets the next token from a tokenizer and converts it to an unsigned 16 bit - * integer. - * @return The next token in the stream, as an unsigned 16 bit integer. - * @throws TextParseException The input was invalid or not an unsigned 16 - * bit integer. - * @throws IOException An I/O error occurred. - */ -public int -getUInt16() throws IOException { - long l = getLong(); - if (l < 0 || l > 0xFFFFL) - throw exception("expected an 16 bit unsigned integer"); - return (int) l; -} - -/** - * Gets the next token from a tokenizer and converts it to an unsigned 8 bit - * integer. - * @return The next token in the stream, as an unsigned 8 bit integer. - * @throws TextParseException The input was invalid or not an unsigned 8 - * bit integer. - * @throws IOException An I/O error occurred. - */ -public int -getUInt8() throws IOException { - long l = getLong(); - if (l < 0 || l > 0xFFL) - throw exception("expected an 8 bit unsigned integer"); - return (int) l; -} - -/** - * Gets the next token from a tokenizer and parses it as a TTL. - * @return The next token in the stream, as an unsigned 32 bit integer. - * @throws TextParseException The input was not valid. - * @throws IOException An I/O error occurred. - * @see TTL - */ -public long -getTTL() throws IOException { - String next = _getIdentifier("a TTL value"); - try { - return TTL.parseTTL(next); - } - catch (NumberFormatException e) { - throw exception("expected a TTL value"); - } -} - -/** - * Gets the next token from a tokenizer and parses it as if it were a TTL. - * @return The next token in the stream, as an unsigned 32 bit integer. - * @throws TextParseException The input was not valid. - * @throws IOException An I/O error occurred. - * @see TTL - */ -public long -getTTLLike() throws IOException { - String next = _getIdentifier("a TTL-like value"); - try { - return TTL.parse(next, false); - } - catch (NumberFormatException e) { - throw exception("expected a TTL-like value"); - } -} - -/** - * Gets the next token from a tokenizer and converts it to a name. - * @param origin The origin to append to relative names. - * @return The next token in the stream, as a name. - * @throws TextParseException The input was invalid or not a valid name. - * @throws IOException An I/O error occurred. - * @throws RelativeNameException The parsed name was relative, even with the - * origin. - * @see Name - */ -public Name -getName(Name origin) throws IOException { - String next = _getIdentifier("a name"); - try { - Name name = Name.fromString(next, origin); - if (!name.isAbsolute()) - throw new RelativeNameException(name); - return name; - } - catch (TextParseException e) { - throw exception(e.getMessage()); - } -} - -/** - * Gets the next token from a tokenizer and converts it to a byte array - * containing an IP address. - * @param family The address family. - * @return The next token in the stream, as an byte array representing an IP - * address. - * @throws TextParseException The input was invalid or not a valid address. - * @throws IOException An I/O error occurred. - * @see Address - */ -public byte [] -getAddressBytes(int family) throws IOException { - String next = _getIdentifier("an address"); - byte [] bytes = Address.toByteArray(next, family); - if (bytes == null) - throw exception("Invalid address: " + next); - return bytes; -} - -/** - * Gets the next token from a tokenizer and converts it to an IP Address. - * @param family The address family. - * @return The next token in the stream, as an InetAddress - * @throws TextParseException The input was invalid or not a valid address. - * @throws IOException An I/O error occurred. - * @see Address - */ -public InetAddress -getAddress(int family) throws IOException { - String next = _getIdentifier("an address"); - try { - return Address.getByAddress(next, family); - } - catch (UnknownHostException e) { - throw exception(e.getMessage()); - } -} - -/** - * Gets the next token from a tokenizer, which must be an EOL or EOF. - * @throws TextParseException The input was invalid or not an EOL or EOF token. - * @throws IOException An I/O error occurred. - */ -public void -getEOL() throws IOException { - Token next = get(); - if (next.type != EOL && next.type != EOF) { - throw exception("expected EOL or EOF"); - } -} - -/** - * Returns a concatenation of the remaining strings from a Tokenizer. - */ -private String -remainingStrings() throws IOException { - StringBuffer buffer = null; - while (true) { - Tokenizer.Token t = get(); - if (!t.isString()) - break; - if (buffer == null) - buffer = new StringBuffer(); - buffer.append(t.value); - } - unget(); - if (buffer == null) - return null; - return buffer.toString(); -} - -/** - * Gets the remaining string tokens until an EOL/EOF is seen, concatenates - * them together, and converts the base64 encoded data to a byte array. - * @param required If true, an exception will be thrown if no strings remain; - * otherwise null be be returned. - * @return The byte array containing the decoded strings, or null if there - * were no strings to decode. - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ -public byte [] -getBase64(boolean required) throws IOException { - String s = remainingStrings(); - if (s == null) { - if (required) - throw exception("expected base64 encoded string"); - else - return null; - } - byte [] array = base64.fromString(s); - if (array == null) - throw exception("invalid base64 encoding"); - return array; -} - -/** - * Gets the remaining string tokens until an EOL/EOF is seen, concatenates - * them together, and converts the base64 encoded data to a byte array. - * @return The byte array containing the decoded strings, or null if there - * were no strings to decode. - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ -public byte [] -getBase64() throws IOException { - return getBase64(false); -} - -/** - * Gets the remaining string tokens until an EOL/EOF is seen, concatenates - * them together, and converts the hex encoded data to a byte array. - * @param required If true, an exception will be thrown if no strings remain; - * otherwise null be be returned. - * @return The byte array containing the decoded strings, or null if there - * were no strings to decode. - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ -public byte [] -getHex(boolean required) throws IOException { - String s = remainingStrings(); - if (s == null) { - if (required) - throw exception("expected hex encoded string"); - else - return null; - } - byte [] array = base16.fromString(s); - if (array == null) - throw exception("invalid hex encoding"); - return array; -} - -/** - * Gets the remaining string tokens until an EOL/EOF is seen, concatenates - * them together, and converts the hex encoded data to a byte array. - * @return The byte array containing the decoded strings, or null if there - * were no strings to decode. - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ -public byte [] -getHex() throws IOException { - return getHex(false); -} - -/** - * Gets the next token from a tokenizer and decodes it as hex. - * @return The byte array containing the decoded string. - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ -public byte [] -getHexString() throws IOException { - String next = _getIdentifier("a hex string"); - byte [] array = base16.fromString(next); - if (array == null) - throw exception("invalid hex encoding"); - return array; -} - -/** - * Gets the next token from a tokenizer and decodes it as base32. - * @param b32 The base32 context to decode with. - * @return The byte array containing the decoded string. - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ -public byte [] -getBase32String(base32 b32) throws IOException { - String next = _getIdentifier("a base32 string"); - byte [] array = b32.fromString(next); - if (array == null) - throw exception("invalid base32 encoding"); - return array; -} - -/** - * Creates an exception which includes the current state in the error message - * @param s The error message to include. - * @return The exception to be thrown - */ -public TextParseException -exception(String s) { - return new TokenizerException(filename, line, s); -} - -/** - * Closes any files opened by this tokenizer. - */ -public void -close() { - if (wantClose) { - try { - is.close(); - } - catch (IOException e) { - } - } -} - -protected void -finalize() { - close(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Type.java b/src/main/java/core/org/xbill/DNS/Type.java deleted file mode 100644 index f4f2081e..00000000 --- a/src/main/java/core/org/xbill/DNS/Type.java +++ /dev/null @@ -1,397 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.util.HashMap; - -/** - * Constants and functions relating to DNS Types - * - * @author Brian Wellington - */ - -public final class Type { - -/** Address */ -public static final int A = 1; - -/** Name server */ -public static final int NS = 2; - -/** Mail destination */ -public static final int MD = 3; - -/** Mail forwarder */ -public static final int MF = 4; - -/** Canonical name (alias) */ -public static final int CNAME = 5; - -/** Start of authority */ -public static final int SOA = 6; - -/** Mailbox domain name */ -public static final int MB = 7; - -/** Mail group member */ -public static final int MG = 8; - -/** Mail rename name */ -public static final int MR = 9; - -/** Null record */ -public static final int NULL = 10; - -/** Well known services */ -public static final int WKS = 11; - -/** Domain name pointer */ -public static final int PTR = 12; - -/** Host information */ -public static final int HINFO = 13; - -/** Mailbox information */ -public static final int MINFO = 14; - -/** Mail routing information */ -public static final int MX = 15; - -/** Text strings */ -public static final int TXT = 16; - -/** Responsible person */ -public static final int RP = 17; - -/** AFS cell database */ -public static final int AFSDB = 18; - -/** X.25 calling address */ -public static final int X25 = 19; - -/** ISDN calling address */ -public static final int ISDN = 20; - -/** Router */ -public static final int RT = 21; - -/** NSAP address */ -public static final int NSAP = 22; - -/** Reverse NSAP address (deprecated) */ -public static final int NSAP_PTR = 23; - -/** Signature */ -public static final int SIG = 24; - -/** Key */ -public static final int KEY = 25; - -/** X.400 mail mapping */ -public static final int PX = 26; - -/** Geographical position (withdrawn) */ -public static final int GPOS = 27; - -/** IPv6 address */ -public static final int AAAA = 28; - -/** Location */ -public static final int LOC = 29; - -/** Next valid name in zone */ -public static final int NXT = 30; - -/** Endpoint identifier */ -public static final int EID = 31; - -/** Nimrod locator */ -public static final int NIMLOC = 32; - -/** Server selection */ -public static final int SRV = 33; - -/** ATM address */ -public static final int ATMA = 34; - -/** Naming authority pointer */ -public static final int NAPTR = 35; - -/** Key exchange */ -public static final int KX = 36; - -/** Certificate */ -public static final int CERT = 37; - -/** IPv6 address (experimental) */ -public static final int A6 = 38; - -/** Non-terminal name redirection */ -public static final int DNAME = 39; - -/** Options - contains EDNS metadata */ -public static final int OPT = 41; - -/** Address Prefix List */ -public static final int APL = 42; - -/** Delegation Signer */ -public static final int DS = 43; - -/** SSH Key Fingerprint */ -public static final int SSHFP = 44; - -/** IPSEC key */ -public static final int IPSECKEY = 45; - -/** Resource Record Signature */ -public static final int RRSIG = 46; - -/** Next Secure Name */ -public static final int NSEC = 47; - -/** DNSSEC Key */ -public static final int DNSKEY = 48; - -/** Dynamic Host Configuration Protocol (DHCP) ID */ -public static final int DHCID = 49; - -/** Next SECure, 3rd edition, RFC 5155 */ -public static final int NSEC3 = 50; - -/** Next SECure PARAMeter, RFC 5155 */ -public static final int NSEC3PARAM = 51; - -/** Transport Layer Security Authentication, draft-ietf-dane-protocol-23 */ -public static final int TLSA = 52; - -/** S/MIME cert association, draft-ietf-dane-smime */ -public static final int SMIMEA = 53; - -/** OpenPGP Key, RFC 7929 */ -public static final int OPENPGPKEY = 61; - -/** - * Service Location and Parameter Binding - * - * @see draft-ietf-dnsop-svcb-https - */ -public static final int SVCB = 64; - -/** - * HTTPS Service Location and Parameter Binding - * - * @see draft-ietf-dnsop-svcb-https - */ -public static final int HTTPS = 65; - -/** Sender Policy Framework (experimental) */ -public static final int SPF = 99; - -/** Transaction key - used to compute a shared secret or exchange a key */ -public static final int TKEY = 249; - -/** Transaction signature */ -public static final int TSIG = 250; - -/** Incremental zone transfer */ -public static final int IXFR = 251; - -/** Zone transfer */ -public static final int AXFR = 252; - -/** Transfer mailbox records */ -public static final int MAILB = 253; - -/** Transfer mail agent records */ -public static final int MAILA = 254; - -/** Matches any type */ -public static final int ANY = 255; - -/** URI - * @see draft-faltstrom-uri-14 - */ -public static final int URI = 256; - -/** Certification Authority Authorization, RFC 6844 */ -public static final int CAA = 257; - -/** DNSSEC Lookaside Validation, RFC 4431 . */ -public static final int DLV = 32769; - - -private static class TypeMnemonic extends Mnemonic { - private HashMap objects; - - public - TypeMnemonic() { - super("Type", CASE_UPPER); - setPrefix("TYPE"); - objects = new HashMap(); - } - - public void - add(int val, String str, Record proto) { - super.add(val, str); - objects.put(Mnemonic.toInteger(val), proto); - } - - public void - check(int val) { - Type.check(val); - } - - public Record - getProto(int val) { - check(val); - return (Record) objects.get(toInteger(val)); - } -} - -private static TypeMnemonic types = new TypeMnemonic(); - -static { - types.add(A, "A", new ARecord()); - types.add(NS, "NS", new NSRecord()); - types.add(MD, "MD", new MDRecord()); - types.add(MF, "MF", new MFRecord()); - types.add(CNAME, "CNAME", new CNAMERecord()); - types.add(SOA, "SOA", new SOARecord()); - types.add(MB, "MB", new MBRecord()); - types.add(MG, "MG", new MGRecord()); - types.add(MR, "MR", new MRRecord()); - types.add(NULL, "NULL", new NULLRecord()); - types.add(WKS, "WKS", new WKSRecord()); - types.add(PTR, "PTR", new PTRRecord()); - types.add(HINFO, "HINFO", new HINFORecord()); - types.add(MINFO, "MINFO", new MINFORecord()); - types.add(MX, "MX", new MXRecord()); - types.add(TXT, "TXT", new TXTRecord()); - types.add(RP, "RP", new RPRecord()); - types.add(AFSDB, "AFSDB", new AFSDBRecord()); - types.add(X25, "X25", new X25Record()); - types.add(ISDN, "ISDN", new ISDNRecord()); - types.add(RT, "RT", new RTRecord()); - types.add(NSAP, "NSAP", new NSAPRecord()); - types.add(NSAP_PTR, "NSAP-PTR", new NSAP_PTRRecord()); - types.add(SIG, "SIG", new SIGRecord()); - types.add(KEY, "KEY", new KEYRecord()); - types.add(PX, "PX", new PXRecord()); - types.add(GPOS, "GPOS", new GPOSRecord()); - types.add(AAAA, "AAAA", new AAAARecord()); - types.add(LOC, "LOC", new LOCRecord()); - types.add(NXT, "NXT", new NXTRecord()); - types.add(EID, "EID"); - types.add(NIMLOC, "NIMLOC"); - types.add(SRV, "SRV", new SRVRecord()); - types.add(ATMA, "ATMA"); - types.add(NAPTR, "NAPTR", new NAPTRRecord()); - types.add(KX, "KX", new KXRecord()); - types.add(CERT, "CERT", new CERTRecord()); - types.add(A6, "A6", new A6Record()); - types.add(DNAME, "DNAME", new DNAMERecord()); - types.add(OPT, "OPT", new OPTRecord()); - types.add(APL, "APL", new APLRecord()); - types.add(DS, "DS", new DSRecord()); - types.add(SSHFP, "SSHFP", new SSHFPRecord()); - types.add(IPSECKEY, "IPSECKEY", new IPSECKEYRecord()); - types.add(RRSIG, "RRSIG", new RRSIGRecord()); - types.add(NSEC, "NSEC", new NSECRecord()); - types.add(DNSKEY, "DNSKEY", new DNSKEYRecord()); - types.add(DHCID, "DHCID", new DHCIDRecord()); - types.add(NSEC3, "NSEC3", new NSEC3Record()); - types.add(NSEC3PARAM, "NSEC3PARAM", new NSEC3PARAMRecord()); - types.add(TLSA, "TLSA", new TLSARecord()); - types.add(SMIMEA, "SMIMEA", new SMIMEARecord()); - types.add(OPENPGPKEY, "OPENPGPKEY", new OPENPGPKEYRecord()); - types.add(SVCB, "SVCB", new SVCBRecord()); - types.add(HTTPS, "HTTPS", new HTTPSRecord()); - types.add(SPF, "SPF", new SPFRecord()); - types.add(TKEY, "TKEY", new TKEYRecord()); - types.add(TSIG, "TSIG", new TSIGRecord()); - types.add(IXFR, "IXFR"); - types.add(AXFR, "AXFR"); - types.add(MAILB, "MAILB"); - types.add(MAILA, "MAILA"); - types.add(ANY, "ANY"); - types.add(URI, "URI", new URIRecord()); - types.add(CAA, "CAA", new CAARecord()); - types.add(DLV, "DLV", new DLVRecord()); -} - -private -Type() { -} - -/** - * Checks that a numeric Type is valid. - * @throws InvalidTypeException The type is out of range. - */ -public static void -check(int val) { - if (val < 0 || val > 0xFFFF) - throw new InvalidTypeException(val); -} - -/** - * Converts a numeric Type into a String - * @param val The type value. - * @return The canonical string representation of the type - * @throws InvalidTypeException The type is out of range. - */ -public static String -string(int val) { - return types.getText(val); -} - -/** - * Converts a String representation of an Type into its numeric value. - * @param s The string representation of the type - * @param numberok Whether a number will be accepted or not. - * @return The type code, or -1 on error. - */ -public static int -value(String s, boolean numberok) { - int val = types.getValue(s); - if (val == -1 && numberok) { - val = types.getValue("TYPE" + s); - } - return val; -} - -/** - * Converts a String representation of an Type into its numeric value - * @return The type code, or -1 on error. - */ -public static int -value(String s) { - return value(s, false); -} - -static Record -getProto(int val) { - return types.getProto(val); -} - -/** Is this type valid for a record (a non-meta type)? */ -public static boolean -isRR(int type) { - switch (type) { - case OPT: - case TKEY: - case TSIG: - case IXFR: - case AXFR: - case MAILB: - case MAILA: - case ANY: - return false; - default: - return true; - } -} - -} diff --git a/src/main/java/core/org/xbill/DNS/TypeBitmap.java b/src/main/java/core/org/xbill/DNS/TypeBitmap.java deleted file mode 100644 index 248d7b19..00000000 --- a/src/main/java/core/org/xbill/DNS/TypeBitmap.java +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) 2004-2009 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * Routines for deal with the lists of types found in NSEC/NSEC3 records. - * - * @author Brian Wellington - */ - -import java.io.*; -import java.util.*; - -final class TypeBitmap implements Serializable { - -private static final long serialVersionUID = -125354057735389003L; - -private TreeSet types; - -private -TypeBitmap() { - types = new TreeSet(); -} - -public -TypeBitmap(int [] array) { - this(); - for (int i = 0; i < array.length; i++) { - Type.check(array[i]); - types.add(array[i]); - } -} - -public -TypeBitmap(DNSInput in) throws WireParseException { - this(); - int lastbase = -1; - while (in.remaining() > 0) { - if (in.remaining() < 2) - throw new WireParseException - ("invalid bitmap descriptor"); - int mapbase = in.readU8(); - if (mapbase < lastbase) - throw new WireParseException("invalid ordering"); - int maplength = in.readU8(); - if (maplength > in.remaining()) - throw new WireParseException("invalid bitmap"); - for (int i = 0; i < maplength; i++) { - int current = in.readU8(); - if (current == 0) - continue; - for (int j = 0; j < 8; j++) { - if ((current & (1 << (7 - j))) == 0) - continue; - int typecode = mapbase * 256 + + i * 8 + j; - types.add(Mnemonic.toInteger(typecode)); - } - } - } -} - -public -TypeBitmap(Tokenizer st) throws IOException { - this(); - while (true) { - Tokenizer.Token t = st.get(); - if (!t.isString()) - break; - int typecode = Type.value(t.value); - if (typecode < 0) { - throw st.exception("Invalid type: " + t.value); - } - types.add(Mnemonic.toInteger(typecode)); - } - st.unget(); -} - -public int [] -toArray() { - int [] array = new int[types.size()]; - int n = 0; - for (Iterator it = types.iterator(); it.hasNext(); ) - array[n++] = ((Integer)it.next()).intValue(); - return array; -} - -public String -toString() { - StringBuffer sb = new StringBuffer(); - for (Iterator it = types.iterator(); it.hasNext(); ) { - int t = ((Integer)it.next()).intValue(); - sb.append(Type.string(t)); - if (it.hasNext()) - sb.append(' '); - } - return sb.toString(); -} - -private static void -mapToWire(DNSOutput out, TreeSet map, int mapbase) { - int arraymax = (((Integer)map.last()).intValue()) & 0xFF; - int arraylength = (arraymax / 8) + 1; - int [] array = new int[arraylength]; - out.writeU8(mapbase); - out.writeU8(arraylength); - for (Iterator it = map.iterator(); it.hasNext(); ) { - int typecode = ((Integer)it.next()).intValue(); - array[(typecode & 0xFF) / 8] |= (1 << ( 7 - typecode % 8)); - } - for (int j = 0; j < arraylength; j++) - out.writeU8(array[j]); -} - -public void -toWire(DNSOutput out) { - if (types.size() == 0) - return; - - int mapbase = -1; - TreeSet map = new TreeSet(); - - for (Iterator it = types.iterator(); it.hasNext(); ) { - int t = ((Integer)it.next()).intValue(); - int base = t >> 8; - if (base != mapbase) { - if (map.size() > 0) { - mapToWire(out, map, mapbase); - map.clear(); - } - mapbase = base; - } - map.add(t); - } - mapToWire(out, map, mapbase); -} - -public boolean -empty() { - return types.isEmpty(); -} - -public boolean -contains(int typecode) { - return types.contains(Mnemonic.toInteger(typecode)); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/U16NameBase.java b/src/main/java/core/org/xbill/DNS/U16NameBase.java deleted file mode 100644 index df3c8364..00000000 --- a/src/main/java/core/org/xbill/DNS/U16NameBase.java +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * Implements common functionality for the many record types whose format - * is an unsigned 16 bit integer followed by a name. - * - * @author Brian Wellington - */ - -abstract class U16NameBase extends Record { - -private static final long serialVersionUID = -8315884183112502995L; - -protected int u16Field; -protected Name nameField; - -protected -U16NameBase() {} - -protected -U16NameBase(Name name, int type, int dclass, long ttl) { - super(name, type, dclass, ttl); -} - -protected -U16NameBase(Name name, int type, int dclass, long ttl, int u16Field, - String u16Description, Name nameField, String nameDescription) -{ - super(name, type, dclass, ttl); - this.u16Field = checkU16(u16Description, u16Field); - this.nameField = checkName(nameDescription, nameField); -} - -void -rrFromWire(DNSInput in) throws IOException { - u16Field = in.readU16(); - nameField = new Name(in); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - u16Field = st.getUInt16(); - nameField = st.getName(origin); -} - -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(u16Field); - sb.append(" "); - sb.append(nameField); - return sb.toString(); -} - -protected int -getU16Field() { - return u16Field; -} - -protected Name -getNameField() { - return nameField; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(u16Field); - nameField.toWire(out, null, canonical); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/UDPClient.java b/src/main/java/core/org/xbill/DNS/UDPClient.java deleted file mode 100644 index 90ebccb2..00000000 --- a/src/main/java/core/org/xbill/DNS/UDPClient.java +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (c) 2005 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.net.*; -import java.security.SecureRandom; -import java.nio.*; -import java.nio.channels.*; - -final class UDPClient extends Client { - -private static final int EPHEMERAL_START = 1024; -private static final int EPHEMERAL_STOP = 65535; -private static final int EPHEMERAL_RANGE = EPHEMERAL_STOP - EPHEMERAL_START; - -private static SecureRandom prng = new SecureRandom(); -private static volatile boolean prng_initializing = true; - -/* - * On some platforms (Windows), the SecureRandom module initialization involves - * a call to InetAddress.getLocalHost(), which can end up here if using a - * dnsjava name service provider. - * - * This can cause problems in multiple ways. - * - If the SecureRandom seed generation process calls into here, and this - * module attempts to seed the local SecureRandom object, the thread hangs. - * - If something else calls InetAddress.getLocalHost(), and that causes this - * module to seed the local SecureRandom object, the thread hangs. - * - * To avoid both of these, check at initialization time to see if InetAddress - * is in the call chain. If so, initialize the SecureRandom object in a new - * thread, and disable port randomization until it completes. - */ -static { - new Thread(new Runnable() { - public void run() { - int n = prng.nextInt(); - prng_initializing = false; - }}).start(); -} - -private boolean bound = false; - -public -UDPClient(long endTime) throws IOException { - super(DatagramChannel.open(), endTime); -} - -private void -bind_random(InetSocketAddress addr) throws IOException -{ - if (prng_initializing) { - try { - Thread.sleep(2); - } - catch (InterruptedException e) { - } - if (prng_initializing) - return; - } - - DatagramChannel channel = (DatagramChannel) key.channel(); - InetSocketAddress temp; - - for (int i = 0; i < 1024; i++) { - try { - int port = prng.nextInt(EPHEMERAL_RANGE) + - EPHEMERAL_START; - if (addr != null) - temp = new InetSocketAddress(addr.getAddress(), - port); - else - temp = new InetSocketAddress(port); - channel.socket().bind(temp); - bound = true; - return; - } - catch (SocketException e) { - } - } -} - -void -bind(SocketAddress addr) throws IOException { - if (addr == null || - (addr instanceof InetSocketAddress && - ((InetSocketAddress)addr).getPort() == 0)) - { - bind_random((InetSocketAddress) addr); - if (bound) - return; - } - - if (addr != null) { - DatagramChannel channel = (DatagramChannel) key.channel(); - channel.socket().bind(addr); - bound = true; - } -} - -void -connect(SocketAddress addr) throws IOException { - if (!bound) - bind(null); - DatagramChannel channel = (DatagramChannel) key.channel(); - channel.connect(addr); -} - -void -send(byte [] data) throws IOException { - DatagramChannel channel = (DatagramChannel) key.channel(); - verboseLog("UDP write", channel.socket().getLocalSocketAddress(), - channel.socket().getRemoteSocketAddress(), data); - channel.write(ByteBuffer.wrap(data)); -} - -byte [] -recv(int max) throws IOException { - DatagramChannel channel = (DatagramChannel) key.channel(); - byte [] temp = new byte[max]; - key.interestOps(SelectionKey.OP_READ); - try { - while (!key.isReadable()) - blockUntil(key, endTime); - } - finally { - if (key.isValid()) - key.interestOps(0); - } - long ret = channel.read(ByteBuffer.wrap(temp)); - if (ret <= 0) - throw new EOFException(); - int len = (int) ret; - byte [] data = new byte[len]; - System.arraycopy(temp, 0, data, 0, len); - verboseLog("UDP read", channel.socket().getLocalSocketAddress(), - channel.socket().getRemoteSocketAddress(), data); - return data; -} - -static byte [] -sendrecv(SocketAddress local, SocketAddress remote, byte [] data, int max, - long endTime) -throws IOException -{ - UDPClient client = new UDPClient(endTime); - try { - client.bind(local); - client.connect(remote); - client.send(data); - return client.recv(max); - } - finally { - client.cleanup(); - } -} - -static byte [] -sendrecv(SocketAddress addr, byte [] data, int max, long endTime) -throws IOException -{ - return sendrecv(null, addr, data, max, endTime); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/UNKRecord.java b/src/main/java/core/org/xbill/DNS/UNKRecord.java deleted file mode 100644 index 91c9697f..00000000 --- a/src/main/java/core/org/xbill/DNS/UNKRecord.java +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * A class implementing Records of unknown and/or unimplemented types. This - * class can only be initialized using static Record initializers. - * - * @author Brian Wellington - */ - -public class UNKRecord extends Record { - -private static final long serialVersionUID = -4193583311594626915L; - -private byte [] data; - -UNKRecord() {} - -Record -getObject() { - return new UNKRecord(); -} - -void -rrFromWire(DNSInput in) throws IOException { - data = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - throw st.exception("invalid unknown RR encoding"); -} - -/** Converts this Record to the String "unknown format" */ -String -rrToString() { - return unknownToString(data); -} - -/** Returns the contents of this record. */ -public byte [] -getData() { - return data; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeByteArray(data); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/URIRecord.java b/src/main/java/core/org/xbill/DNS/URIRecord.java deleted file mode 100644 index 4859150d..00000000 --- a/src/main/java/core/org/xbill/DNS/URIRecord.java +++ /dev/null @@ -1,108 +0,0 @@ -// Implemented by Anthony Kirby (anthony@anthony.org) -// based on SRVRecord.java Copyright (c) 1999-2004 Brian Wellington - -package org.xbill.DNS; - -import java.io.*; - -/** - * Uniform Resource Identifier (URI) DNS Resource Record - * - * @author Anthony Kirby - * @see http://tools.ietf.org/html/draft-faltstrom-uri - */ - -public class URIRecord extends Record { - -private static final long serialVersionUID = 7955422413971804232L; - -private int priority, weight; -private byte[] target; - -URIRecord() { - target = new byte[]{}; -} - -Record -getObject() { - return new URIRecord(); -} - -/** - * Creates a URI Record from the given data - * @param priority The priority of this URI. Records with lower priority - * are preferred. - * @param weight The weight, used to select between records at the same - * priority. - * @param target The host/port running the service - */ -public -URIRecord(Name name, int dclass, long ttl, int priority, - int weight, String target) -{ - super(name, Type.URI, dclass, ttl); - this.priority = checkU16("priority", priority); - this.weight = checkU16("weight", weight); - try { - this.target = byteArrayFromString(target); - } - catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } -} - -void -rrFromWire(DNSInput in) throws IOException { - priority = in.readU16(); - weight = in.readU16(); - target = in.readByteArray(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - priority = st.getUInt16(); - weight = st.getUInt16(); - try { - target = byteArrayFromString(st.getString()); - } - catch (TextParseException e) { - throw st.exception(e.getMessage()); - } -} - -/** Converts rdata to a String */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(priority + " "); - sb.append(weight + " "); - sb.append(byteArrayToString(target, true)); - return sb.toString(); -} - -/** Returns the priority */ -public int -getPriority() { - return priority; -} - -/** Returns the weight */ -public int -getWeight() { - return weight; -} - -/** Returns the target URI */ -public String -getTarget() { - return byteArrayToString(target, false); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeU16(priority); - out.writeU16(weight); - out.writeByteArray(target); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Update.java b/src/main/java/core/org/xbill/DNS/Update.java deleted file mode 100644 index 02a920b6..00000000 --- a/src/main/java/core/org/xbill/DNS/Update.java +++ /dev/null @@ -1,300 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; - -/** - * A helper class for constructing dynamic DNS (DDNS) update messages. - * - * @author Brian Wellington - */ - -public class Update extends Message { - -private Name origin; -private int dclass; - -/** - * Creates an update message. - * @param zone The name of the zone being updated. - * @param dclass The class of the zone being updated. - */ -public -Update(Name zone, int dclass) { - super(); - if (!zone.isAbsolute()) - throw new RelativeNameException(zone); - DClass.check(dclass); - getHeader().setOpcode(Opcode.UPDATE); - Record soa = Record.newRecord(zone, Type.SOA, DClass.IN); - addRecord(soa, Section.QUESTION); - this.origin = zone; - this.dclass = dclass; -} - -/** - * Creates an update message. The class is assumed to be IN. - * @param zone The name of the zone being updated. - */ -public -Update(Name zone) { - this(zone, DClass.IN); -} - -private void -newPrereq(Record rec) { - addRecord(rec, Section.PREREQ); -} - -private void -newUpdate(Record rec) { - addRecord(rec, Section.UPDATE); -} - -/** - * Inserts a prerequisite that the specified name exists; that is, there - * exist records with the given name in the zone. - */ -public void -present(Name name) { - newPrereq(Record.newRecord(name, Type.ANY, DClass.ANY, 0)); -} - -/** - * Inserts a prerequisite that the specified rrset exists; that is, there - * exist records with the given name and type in the zone. - */ -public void -present(Name name, int type) { - newPrereq(Record.newRecord(name, type, DClass.ANY, 0)); -} - -/** - * Parses a record from the string, and inserts a prerequisite that the - * record exists. Due to the way value-dependent prequisites work, the - * condition that must be met is that the set of all records with the same - * and type in the update message must be identical to the set of all records - * with that name and type on the server. - * @throws IOException The record could not be parsed. - */ -public void -present(Name name, int type, String record) throws IOException { - newPrereq(Record.fromString(name, type, dclass, 0, record, origin)); -} - -/** - * Parses a record from the tokenizer, and inserts a prerequisite that the - * record exists. Due to the way value-dependent prequisites work, the - * condition that must be met is that the set of all records with the same - * and type in the update message must be identical to the set of all records - * with that name and type on the server. - * @throws IOException The record could not be parsed. - */ -public void -present(Name name, int type, Tokenizer tokenizer) throws IOException { - newPrereq(Record.fromString(name, type, dclass, 0, tokenizer, origin)); -} - -/** - * Inserts a prerequisite that the specified record exists. Due to the way - * value-dependent prequisites work, the condition that must be met is that - * the set of all records with the same and type in the update message must - * be identical to the set of all records with that name and type on the server. - */ -public void -present(Record record) { - newPrereq(record); -} - -/** - * Inserts a prerequisite that the specified name does not exist; that is, - * there are no records with the given name in the zone. - */ -public void -absent(Name name) { - newPrereq(Record.newRecord(name, Type.ANY, DClass.NONE, 0)); -} - -/** - * Inserts a prerequisite that the specified rrset does not exist; that is, - * there are no records with the given name and type in the zone. - */ -public void -absent(Name name, int type) { - newPrereq(Record.newRecord(name, type, DClass.NONE, 0)); -} - -/** - * Parses a record from the string, and indicates that the record - * should be inserted into the zone. - * @throws IOException The record could not be parsed. - */ -public void -add(Name name, int type, long ttl, String record) throws IOException { - newUpdate(Record.fromString(name, type, dclass, ttl, record, origin)); -} - -/** - * Parses a record from the tokenizer, and indicates that the record - * should be inserted into the zone. - * @throws IOException The record could not be parsed. - */ -public void -add(Name name, int type, long ttl, Tokenizer tokenizer) throws IOException { - newUpdate(Record.fromString(name, type, dclass, ttl, tokenizer, - origin)); -} - -/** - * Indicates that the record should be inserted into the zone. - */ -public void -add(Record record) { - newUpdate(record); -} - -/** - * Indicates that the records should be inserted into the zone. - */ -public void -add(Record [] records) { - for (int i = 0; i < records.length; i++) - add(records[i]); -} - -/** - * Indicates that all of the records in the rrset should be inserted into the - * zone. - */ -public void -add(RRset rrset) { - for (Iterator it = rrset.rrs(); it.hasNext(); ) - add((Record) it.next()); -} - -/** - * Indicates that all records with the given name should be deleted from - * the zone. - */ -public void -delete(Name name) { - newUpdate(Record.newRecord(name, Type.ANY, DClass.ANY, 0)); -} - -/** - * Indicates that all records with the given name and type should be deleted - * from the zone. - */ -public void -delete(Name name, int type) { - newUpdate(Record.newRecord(name, type, DClass.ANY, 0)); -} - -/** - * Parses a record from the string, and indicates that the record - * should be deleted from the zone. - * @throws IOException The record could not be parsed. - */ -public void -delete(Name name, int type, String record) throws IOException { - newUpdate(Record.fromString(name, type, DClass.NONE, 0, record, - origin)); -} - -/** - * Parses a record from the tokenizer, and indicates that the record - * should be deleted from the zone. - * @throws IOException The record could not be parsed. - */ -public void -delete(Name name, int type, Tokenizer tokenizer) throws IOException { - newUpdate(Record.fromString(name, type, DClass.NONE, 0, tokenizer, - origin)); -} - -/** - * Indicates that the specified record should be deleted from the zone. - */ -public void -delete(Record record) { - newUpdate(record.withDClass(DClass.NONE, 0)); -} - -/** - * Indicates that the records should be deleted from the zone. - */ -public void -delete(Record [] records) { - for (int i = 0; i < records.length; i++) - delete(records[i]); -} - -/** - * Indicates that all of the records in the rrset should be deleted from the - * zone. - */ -public void -delete(RRset rrset) { - for (Iterator it = rrset.rrs(); it.hasNext(); ) - delete((Record) it.next()); -} - -/** - * Parses a record from the string, and indicates that the record - * should be inserted into the zone replacing any other records with the - * same name and type. - * @throws IOException The record could not be parsed. - */ -public void -replace(Name name, int type, long ttl, String record) throws IOException { - delete(name, type); - add(name, type, ttl, record); -} - -/** - * Parses a record from the tokenizer, and indicates that the record - * should be inserted into the zone replacing any other records with the - * same name and type. - * @throws IOException The record could not be parsed. - */ -public void -replace(Name name, int type, long ttl, Tokenizer tokenizer) throws IOException -{ - delete(name, type); - add(name, type, ttl, tokenizer); -} - -/** - * Indicates that the record should be inserted into the zone replacing any - * other records with the same name and type. - */ -public void -replace(Record record) { - delete(record.getName(), record.getType()); - add(record); -} - -/** - * Indicates that the records should be inserted into the zone replacing any - * other records with the same name and type as each one. - */ -public void -replace(Record [] records) { - for (int i = 0; i < records.length; i++) - replace(records[i]); -} - -/** - * Indicates that all of the records in the rrset should be inserted into the - * zone replacing any other records with the same name and type. - */ -public void -replace(RRset rrset) { - delete(rrset.getName(), rrset.getType()); - for (Iterator it = rrset.rrs(); it.hasNext(); ) - add((Record) it.next()); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/WKSRecord.java b/src/main/java/core/org/xbill/DNS/WKSRecord.java deleted file mode 100644 index dcc8891c..00000000 --- a/src/main/java/core/org/xbill/DNS/WKSRecord.java +++ /dev/null @@ -1,719 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.net.*; -import java.io.*; -import java.util.*; - -/** - * Well Known Services - Lists services offered by this host. - * - * @author Brian Wellington - */ - -public class WKSRecord extends Record { - -private static final long serialVersionUID = -9104259763909119805L; - -public static class Protocol { - /** - * IP protocol identifiers. This is basically copied out of RFC 1010. - */ - - private Protocol() {} - - /** Internet Control Message */ - public static final int ICMP = 1; - - /** Internet Group Management */ - public static final int IGMP = 2; - - /** Gateway-to-Gateway */ - public static final int GGP = 3; - - /** Stream */ - public static final int ST = 5; - - /** Transmission Control */ - public static final int TCP = 6; - - /** UCL */ - public static final int UCL = 7; - - /** Exterior Gateway Protocol */ - public static final int EGP = 8; - - /** any private interior gateway */ - public static final int IGP = 9; - - /** BBN RCC Monitoring */ - public static final int BBN_RCC_MON = 10; - - /** Network Voice Protocol */ - public static final int NVP_II = 11; - - /** PUP */ - public static final int PUP = 12; - - /** ARGUS */ - public static final int ARGUS = 13; - - /** EMCON */ - public static final int EMCON = 14; - - /** Cross Net Debugger */ - public static final int XNET = 15; - - /** Chaos */ - public static final int CHAOS = 16; - - /** User Datagram */ - public static final int UDP = 17; - - /** Multiplexing */ - public static final int MUX = 18; - - /** DCN Measurement Subsystems */ - public static final int DCN_MEAS = 19; - - /** Host Monitoring */ - public static final int HMP = 20; - - /** Packet Radio Measurement */ - public static final int PRM = 21; - - /** XEROX NS IDP */ - public static final int XNS_IDP = 22; - - /** Trunk-1 */ - public static final int TRUNK_1 = 23; - - /** Trunk-2 */ - public static final int TRUNK_2 = 24; - - /** Leaf-1 */ - public static final int LEAF_1 = 25; - - /** Leaf-2 */ - public static final int LEAF_2 = 26; - - /** Reliable Data Protocol */ - public static final int RDP = 27; - - /** Internet Reliable Transaction */ - public static final int IRTP = 28; - - /** ISO Transport Protocol Class 4 */ - public static final int ISO_TP4 = 29; - - /** Bulk Data Transfer Protocol */ - public static final int NETBLT = 30; - - /** MFE Network Services Protocol */ - public static final int MFE_NSP = 31; - - /** MERIT Internodal Protocol */ - public static final int MERIT_INP = 32; - - /** Sequential Exchange Protocol */ - public static final int SEP = 33; - - /** CFTP */ - public static final int CFTP = 62; - - /** SATNET and Backroom EXPAK */ - public static final int SAT_EXPAK = 64; - - /** MIT Subnet Support */ - public static final int MIT_SUBNET = 65; - - /** MIT Remote Virtual Disk Protocol */ - public static final int RVD = 66; - - /** Internet Pluribus Packet Core */ - public static final int IPPC = 67; - - /** SATNET Monitoring */ - public static final int SAT_MON = 69; - - /** Internet Packet Core Utility */ - public static final int IPCV = 71; - - /** Backroom SATNET Monitoring */ - public static final int BR_SAT_MON = 76; - - /** WIDEBAND Monitoring */ - public static final int WB_MON = 78; - - /** WIDEBAND EXPAK */ - public static final int WB_EXPAK = 79; - - private static Mnemonic protocols = new Mnemonic("IP protocol", - Mnemonic.CASE_LOWER); - - static { - protocols.setMaximum(0xFF); - protocols.setNumericAllowed(true); - - protocols.add(ICMP, "icmp"); - protocols.add(IGMP, "igmp"); - protocols.add(GGP, "ggp"); - protocols.add(ST, "st"); - protocols.add(TCP, "tcp"); - protocols.add(UCL, "ucl"); - protocols.add(EGP, "egp"); - protocols.add(IGP, "igp"); - protocols.add(BBN_RCC_MON, "bbn-rcc-mon"); - protocols.add(NVP_II, "nvp-ii"); - protocols.add(PUP, "pup"); - protocols.add(ARGUS, "argus"); - protocols.add(EMCON, "emcon"); - protocols.add(XNET, "xnet"); - protocols.add(CHAOS, "chaos"); - protocols.add(UDP, "udp"); - protocols.add(MUX, "mux"); - protocols.add(DCN_MEAS, "dcn-meas"); - protocols.add(HMP, "hmp"); - protocols.add(PRM, "prm"); - protocols.add(XNS_IDP, "xns-idp"); - protocols.add(TRUNK_1, "trunk-1"); - protocols.add(TRUNK_2, "trunk-2"); - protocols.add(LEAF_1, "leaf-1"); - protocols.add(LEAF_2, "leaf-2"); - protocols.add(RDP, "rdp"); - protocols.add(IRTP, "irtp"); - protocols.add(ISO_TP4, "iso-tp4"); - protocols.add(NETBLT, "netblt"); - protocols.add(MFE_NSP, "mfe-nsp"); - protocols.add(MERIT_INP, "merit-inp"); - protocols.add(SEP, "sep"); - protocols.add(CFTP, "cftp"); - protocols.add(SAT_EXPAK, "sat-expak"); - protocols.add(MIT_SUBNET, "mit-subnet"); - protocols.add(RVD, "rvd"); - protocols.add(IPPC, "ippc"); - protocols.add(SAT_MON, "sat-mon"); - protocols.add(IPCV, "ipcv"); - protocols.add(BR_SAT_MON, "br-sat-mon"); - protocols.add(WB_MON, "wb-mon"); - protocols.add(WB_EXPAK, "wb-expak"); - } - - /** - * Converts an IP protocol value into its textual representation - */ - public static String - string(int type) { - return protocols.getText(type); - } - - /** - * Converts a textual representation of an IP protocol into its - * numeric code. Integers in the range 0..255 are also accepted. - * @param s The textual representation of the protocol - * @return The protocol code, or -1 on error. - */ - public static int - value(String s) { - return protocols.getValue(s); - } -} - -public static class Service { - /** - * TCP/UDP services. This is basically copied out of RFC 1010, - * with MIT-ML-DEV removed, as it is not unique, and the description - * of SWIFT-RVF fixed. - */ - - private Service() {} - - /** Remote Job Entry */ - public static final int RJE = 5; - - /** Echo */ - public static final int ECHO = 7; - - /** Discard */ - public static final int DISCARD = 9; - - /** Active Users */ - public static final int USERS = 11; - - /** Daytime */ - public static final int DAYTIME = 13; - - /** Quote of the Day */ - public static final int QUOTE = 17; - - /** Character Generator */ - public static final int CHARGEN = 19; - - /** File Transfer [Default Data] */ - public static final int FTP_DATA = 20; - - /** File Transfer [Control] */ - public static final int FTP = 21; - - /** Telnet */ - public static final int TELNET = 23; - - /** Simple Mail Transfer */ - public static final int SMTP = 25; - - /** NSW User System FE */ - public static final int NSW_FE = 27; - - /** MSG ICP */ - public static final int MSG_ICP = 29; - - /** MSG Authentication */ - public static final int MSG_AUTH = 31; - - /** Display Support Protocol */ - public static final int DSP = 33; - - /** Time */ - public static final int TIME = 37; - - /** Resource Location Protocol */ - public static final int RLP = 39; - - /** Graphics */ - public static final int GRAPHICS = 41; - - /** Host Name Server */ - public static final int NAMESERVER = 42; - - /** Who Is */ - public static final int NICNAME = 43; - - /** MPM FLAGS Protocol */ - public static final int MPM_FLAGS = 44; - - /** Message Processing Module [recv] */ - public static final int MPM = 45; - - /** MPM [default send] */ - public static final int MPM_SND = 46; - - /** NI FTP */ - public static final int NI_FTP = 47; - - /** Login Host Protocol */ - public static final int LOGIN = 49; - - /** IMP Logical Address Maintenance */ - public static final int LA_MAINT = 51; - - /** Domain Name Server */ - public static final int DOMAIN = 53; - - /** ISI Graphics Language */ - public static final int ISI_GL = 55; - - /** NI MAIL */ - public static final int NI_MAIL = 61; - - /** VIA Systems - FTP */ - public static final int VIA_FTP = 63; - - /** TACACS-Database Service */ - public static final int TACACS_DS = 65; - - /** Bootstrap Protocol Server */ - public static final int BOOTPS = 67; - - /** Bootstrap Protocol Client */ - public static final int BOOTPC = 68; - - /** Trivial File Transfer */ - public static final int TFTP = 69; - - /** Remote Job Service */ - public static final int NETRJS_1 = 71; - - /** Remote Job Service */ - public static final int NETRJS_2 = 72; - - /** Remote Job Service */ - public static final int NETRJS_3 = 73; - - /** Remote Job Service */ - public static final int NETRJS_4 = 74; - - /** Finger */ - public static final int FINGER = 79; - - /** HOSTS2 Name Server */ - public static final int HOSTS2_NS = 81; - - /** SU/MIT Telnet Gateway */ - public static final int SU_MIT_TG = 89; - - /** MIT Dover Spooler */ - public static final int MIT_DOV = 91; - - /** Device Control Protocol */ - public static final int DCP = 93; - - /** SUPDUP */ - public static final int SUPDUP = 95; - - /** Swift Remote Virtual File Protocol */ - public static final int SWIFT_RVF = 97; - - /** TAC News */ - public static final int TACNEWS = 98; - - /** Metagram Relay */ - public static final int METAGRAM = 99; - - /** NIC Host Name Server */ - public static final int HOSTNAME = 101; - - /** ISO-TSAP */ - public static final int ISO_TSAP = 102; - - /** X400 */ - public static final int X400 = 103; - - /** X400-SND */ - public static final int X400_SND = 104; - - /** Mailbox Name Nameserver */ - public static final int CSNET_NS = 105; - - /** Remote Telnet Service */ - public static final int RTELNET = 107; - - /** Post Office Protocol - Version 2 */ - public static final int POP_2 = 109; - - /** SUN Remote Procedure Call */ - public static final int SUNRPC = 111; - - /** Authentication Service */ - public static final int AUTH = 113; - - /** Simple File Transfer Protocol */ - public static final int SFTP = 115; - - /** UUCP Path Service */ - public static final int UUCP_PATH = 117; - - /** Network News Transfer Protocol */ - public static final int NNTP = 119; - - /** HYDRA Expedited Remote Procedure */ - public static final int ERPC = 121; - - /** Network Time Protocol */ - public static final int NTP = 123; - - /** Locus PC-Interface Net Map Server */ - public static final int LOCUS_MAP = 125; - - /** Locus PC-Interface Conn Server */ - public static final int LOCUS_CON = 127; - - /** Password Generator Protocol */ - public static final int PWDGEN = 129; - - /** CISCO FNATIVE */ - public static final int CISCO_FNA = 130; - - /** CISCO TNATIVE */ - public static final int CISCO_TNA = 131; - - /** CISCO SYSMAINT */ - public static final int CISCO_SYS = 132; - - /** Statistics Service */ - public static final int STATSRV = 133; - - /** INGRES-NET Service */ - public static final int INGRES_NET = 134; - - /** Location Service */ - public static final int LOC_SRV = 135; - - /** PROFILE Naming System */ - public static final int PROFILE = 136; - - /** NETBIOS Name Service */ - public static final int NETBIOS_NS = 137; - - /** NETBIOS Datagram Service */ - public static final int NETBIOS_DGM = 138; - - /** NETBIOS Session Service */ - public static final int NETBIOS_SSN = 139; - - /** EMFIS Data Service */ - public static final int EMFIS_DATA = 140; - - /** EMFIS Control Service */ - public static final int EMFIS_CNTL = 141; - - /** Britton-Lee IDM */ - public static final int BL_IDM = 142; - - /** Survey Measurement */ - public static final int SUR_MEAS = 243; - - /** LINK */ - public static final int LINK = 245; - - private static Mnemonic services = new Mnemonic("TCP/UDP service", - Mnemonic.CASE_LOWER); - - static { - services.setMaximum(0xFFFF); - services.setNumericAllowed(true); - - services.add(RJE, "rje"); - services.add(ECHO, "echo"); - services.add(DISCARD, "discard"); - services.add(USERS, "users"); - services.add(DAYTIME, "daytime"); - services.add(QUOTE, "quote"); - services.add(CHARGEN, "chargen"); - services.add(FTP_DATA, "ftp-data"); - services.add(FTP, "ftp"); - services.add(TELNET, "telnet"); - services.add(SMTP, "smtp"); - services.add(NSW_FE, "nsw-fe"); - services.add(MSG_ICP, "msg-icp"); - services.add(MSG_AUTH, "msg-auth"); - services.add(DSP, "dsp"); - services.add(TIME, "time"); - services.add(RLP, "rlp"); - services.add(GRAPHICS, "graphics"); - services.add(NAMESERVER, "nameserver"); - services.add(NICNAME, "nicname"); - services.add(MPM_FLAGS, "mpm-flags"); - services.add(MPM, "mpm"); - services.add(MPM_SND, "mpm-snd"); - services.add(NI_FTP, "ni-ftp"); - services.add(LOGIN, "login"); - services.add(LA_MAINT, "la-maint"); - services.add(DOMAIN, "domain"); - services.add(ISI_GL, "isi-gl"); - services.add(NI_MAIL, "ni-mail"); - services.add(VIA_FTP, "via-ftp"); - services.add(TACACS_DS, "tacacs-ds"); - services.add(BOOTPS, "bootps"); - services.add(BOOTPC, "bootpc"); - services.add(TFTP, "tftp"); - services.add(NETRJS_1, "netrjs-1"); - services.add(NETRJS_2, "netrjs-2"); - services.add(NETRJS_3, "netrjs-3"); - services.add(NETRJS_4, "netrjs-4"); - services.add(FINGER, "finger"); - services.add(HOSTS2_NS, "hosts2-ns"); - services.add(SU_MIT_TG, "su-mit-tg"); - services.add(MIT_DOV, "mit-dov"); - services.add(DCP, "dcp"); - services.add(SUPDUP, "supdup"); - services.add(SWIFT_RVF, "swift-rvf"); - services.add(TACNEWS, "tacnews"); - services.add(METAGRAM, "metagram"); - services.add(HOSTNAME, "hostname"); - services.add(ISO_TSAP, "iso-tsap"); - services.add(X400, "x400"); - services.add(X400_SND, "x400-snd"); - services.add(CSNET_NS, "csnet-ns"); - services.add(RTELNET, "rtelnet"); - services.add(POP_2, "pop-2"); - services.add(SUNRPC, "sunrpc"); - services.add(AUTH, "auth"); - services.add(SFTP, "sftp"); - services.add(UUCP_PATH, "uucp-path"); - services.add(NNTP, "nntp"); - services.add(ERPC, "erpc"); - services.add(NTP, "ntp"); - services.add(LOCUS_MAP, "locus-map"); - services.add(LOCUS_CON, "locus-con"); - services.add(PWDGEN, "pwdgen"); - services.add(CISCO_FNA, "cisco-fna"); - services.add(CISCO_TNA, "cisco-tna"); - services.add(CISCO_SYS, "cisco-sys"); - services.add(STATSRV, "statsrv"); - services.add(INGRES_NET, "ingres-net"); - services.add(LOC_SRV, "loc-srv"); - services.add(PROFILE, "profile"); - services.add(NETBIOS_NS, "netbios-ns"); - services.add(NETBIOS_DGM, "netbios-dgm"); - services.add(NETBIOS_SSN, "netbios-ssn"); - services.add(EMFIS_DATA, "emfis-data"); - services.add(EMFIS_CNTL, "emfis-cntl"); - services.add(BL_IDM, "bl-idm"); - services.add(SUR_MEAS, "sur-meas"); - services.add(LINK, "link"); - } - - /** - * Converts a TCP/UDP service port number into its textual - * representation. - */ - public static String - string(int type) { - return services.getText(type); - } - - /** - * Converts a textual representation of a TCP/UDP service into its - * port number. Integers in the range 0..65535 are also accepted. - * @param s The textual representation of the service. - * @return The port number, or -1 on error. - */ - public static int - value(String s) { - return services.getValue(s); - } -} -private byte [] address; -private int protocol; -private int [] services; - -WKSRecord() {} - -Record -getObject() { - return new WKSRecord(); -} - -/** - * Creates a WKS Record from the given data - * @param address The IP address - * @param protocol The IP protocol number - * @param services An array of supported services, represented by port number. - */ -public -WKSRecord(Name name, int dclass, long ttl, InetAddress address, int protocol, - int [] services) -{ - super(name, Type.WKS, dclass, ttl); - if (Address.familyOf(address) != Address.IPv4) - throw new IllegalArgumentException("invalid IPv4 address"); - this.address = address.getAddress(); - this.protocol = checkU8("protocol", protocol); - for (int i = 0; i < services.length; i++) { - checkU16("service", services[i]); - } - this.services = new int[services.length]; - System.arraycopy(services, 0, this.services, 0, services.length); - Arrays.sort(this.services); -} - -void -rrFromWire(DNSInput in) throws IOException { - address = in.readByteArray(4); - protocol = in.readU8(); - byte [] array = in.readByteArray(); - List list = new ArrayList(); - for (int i = 0; i < array.length; i++) { - for (int j = 0; j < 8; j++) { - int octet = array[i] & 0xFF; - if ((octet & (1 << (7 - j))) != 0) { - list.add(i * 8 + j); - } - } - } - services = new int[list.size()]; - for (int i = 0; i < list.size(); i++) { - services[i] = ((Integer) list.get(i)).intValue(); - } -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - String s = st.getString(); - address = Address.toByteArray(s, Address.IPv4); - if (address == null) - throw st.exception("invalid address"); - - s = st.getString(); - protocol = Protocol.value(s); - if (protocol < 0) { - throw st.exception("Invalid IP protocol: " + s); - } - - List list = new ArrayList(); - while (true) { - Tokenizer.Token t = st.get(); - if (!t.isString()) - break; - int service = Service.value(t.value); - if (service < 0) { - throw st.exception("Invalid TCP/UDP service: " + - t.value); - } - list.add(service); - } - st.unget(); - services = new int[list.size()]; - for (int i = 0; i < list.size(); i++) { - services[i] = ((Integer) list.get(i)).intValue(); - } -} - -/** - * Converts rdata to a String - */ -String -rrToString() { - StringBuffer sb = new StringBuffer(); - sb.append(Address.toDottedQuad(address)); - sb.append(" "); - sb.append(protocol); - for (int i = 0; i < services.length; i++) { - sb.append(" " + services[i]); - } - return sb.toString(); -} - -/** - * Returns the IP address. - */ -public InetAddress -getAddress() { - try { - return InetAddress.getByAddress(address); - } catch (UnknownHostException e) { - return null; - } -} - -/** - * Returns the IP protocol. - */ -public int -getProtocol() { - return protocol; -} - -/** - * Returns the services provided by the host on the specified address. - */ -public int [] -getServices() { - return services; -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeByteArray(address); - out.writeU8(protocol); - int highestPort = services[services.length - 1]; - byte [] array = new byte[highestPort / 8 + 1]; - for (int i = 0; i < services.length; i++) { - int port = services[i]; - array[port / 8] |= (1 << (7 - port % 8)); - } - out.writeByteArray(array); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/WireParseException.java b/src/main/java/core/org/xbill/DNS/WireParseException.java deleted file mode 100644 index 28427317..00000000 --- a/src/main/java/core/org/xbill/DNS/WireParseException.java +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * An exception thrown when a DNS message is invalid. - * - * @author Brian Wellington - */ - -public class WireParseException extends IOException { - -public -WireParseException() { - super(); -} - -public -WireParseException(String s) { - super(s); -} - -public -WireParseException(String s, Throwable cause) { - super(s); - initCause(cause); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/X25Record.java b/src/main/java/core/org/xbill/DNS/X25Record.java deleted file mode 100644 index 1349a1e7..00000000 --- a/src/main/java/core/org/xbill/DNS/X25Record.java +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; - -/** - * X25 - identifies the PSDN (Public Switched Data Network) address in the - * X.121 numbering plan associated with a name. - * - * @author Brian Wellington - */ - -public class X25Record extends Record { - -private static final long serialVersionUID = 4267576252335579764L; - -private byte [] address; - -X25Record() {} - -Record -getObject() { - return new X25Record(); -} - -private static final byte [] -checkAndConvertAddress(String address) { - int length = address.length(); - byte [] out = new byte [length]; - for (int i = 0; i < length; i++) { - char c = address.charAt(i); - if (!Character.isDigit(c)) - return null; - out[i] = (byte) c; - } - return out; -} - -/** - * Creates an X25 Record from the given data - * @param address The X.25 PSDN address. - * @throws IllegalArgumentException The address is not a valid PSDN address. - */ -public -X25Record(Name name, int dclass, long ttl, String address) { - super(name, Type.X25, dclass, ttl); - this.address = checkAndConvertAddress(address); - if (this.address == null) { - throw new IllegalArgumentException("invalid PSDN address " + - address); - } -} - -void -rrFromWire(DNSInput in) throws IOException { - address = in.readCountedString(); -} - -void -rdataFromString(Tokenizer st, Name origin) throws IOException { - String addr = st.getString(); - this.address = checkAndConvertAddress(addr); - if (this.address == null) - throw st.exception("invalid PSDN address " + addr); -} - -/** - * Returns the X.25 PSDN address. - */ -public String -getAddress() { - return byteArrayToString(address, false); -} - -void -rrToWire(DNSOutput out, Compression c, boolean canonical) { - out.writeCountedString(address); -} - -String -rrToString() { - return byteArrayToString(address, true); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/Zone.java b/src/main/java/core/org/xbill/DNS/Zone.java deleted file mode 100644 index 866be77e..00000000 --- a/src/main/java/core/org/xbill/DNS/Zone.java +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -import java.io.*; -import java.util.*; - -/** - * A DNS Zone. This encapsulates all data related to a Zone, and provides - * convenient lookup methods. - * - * @author Brian Wellington - */ - -public class Zone implements Serializable { - -private static final long serialVersionUID = -9220510891189510942L; - -/** A primary zone */ -public static final int PRIMARY = 1; - -/** A secondary zone */ -public static final int SECONDARY = 2; - -private Map data; -private Name origin; -private Object originNode; -private int dclass = DClass.IN; -private RRset NS; -private SOARecord SOA; -private boolean hasWild; - -class ZoneIterator implements Iterator { - private Iterator zentries; - private RRset [] current; - private int count; - private boolean wantLastSOA; - - ZoneIterator(boolean axfr) { - synchronized (Zone.this) { - zentries = data.entrySet().iterator(); - } - wantLastSOA = axfr; - RRset [] sets = allRRsets(originNode); - current = new RRset[sets.length]; - for (int i = 0, j = 2; i < sets.length; i++) { - int type = sets[i].getType(); - if (type == Type.SOA) - current[0] = sets[i]; - else if (type == Type.NS) - current[1] = sets[i]; - else - current[j++] = sets[i]; - } - } - - public boolean - hasNext() { - return (current != null || wantLastSOA); - } - - public Object - next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - if (current == null) { - wantLastSOA = false; - return oneRRset(originNode, Type.SOA); - } - Object set = current[count++]; - if (count == current.length) { - current = null; - while (zentries.hasNext()) { - Map.Entry entry = (Map.Entry) zentries.next(); - if (entry.getKey().equals(origin)) - continue; - RRset [] sets = allRRsets(entry.getValue()); - if (sets.length == 0) - continue; - current = sets; - count = 0; - break; - } - } - return set; - } - - public void - remove() { - throw new UnsupportedOperationException(); - } -} - -private void -validate() throws IOException { - originNode = exactName(origin); - if (originNode == null) - throw new IOException(origin + ": no data specified"); - - RRset rrset = oneRRset(originNode, Type.SOA); - if (rrset == null || rrset.size() != 1) - throw new IOException(origin + - ": exactly 1 SOA must be specified"); - Iterator it = rrset.rrs(); - SOA = (SOARecord) it.next(); - - NS = oneRRset(originNode, Type.NS); - if (NS == null) - throw new IOException(origin + ": no NS set specified"); -} - -private final void -maybeAddRecord(Record record) throws IOException { - int rtype = record.getType(); - Name name = record.getName(); - - if (rtype == Type.SOA && !name.equals(origin)) { - throw new IOException("SOA owner " + name + - " does not match zone origin " + - origin); - } - if (name.subdomain(origin)) - addRecord(record); -} - -/** - * Creates a Zone from the records in the specified master file. - * @param zone The name of the zone. - * @param file The master file to read from. - * @see Master - */ -public -Zone(Name zone, String file) throws IOException { - data = new TreeMap(); - - if (zone == null) - throw new IllegalArgumentException("no zone name specified"); - Master m = new Master(file, zone); - Record record; - - origin = zone; - while ((record = m.nextRecord()) != null) - maybeAddRecord(record); - validate(); -} - -/** - * Creates a Zone from an array of records. - * @param zone The name of the zone. - * @param records The records to add to the zone. - * @see Master - */ -public -Zone(Name zone, Record [] records) throws IOException { - data = new TreeMap(); - - if (zone == null) - throw new IllegalArgumentException("no zone name specified"); - origin = zone; - for (int i = 0; i < records.length; i++) - maybeAddRecord(records[i]); - validate(); -} - -private void -fromXFR(ZoneTransferIn xfrin) throws IOException, ZoneTransferException { - data = new TreeMap(); - - origin = xfrin.getName(); - List records = xfrin.run(); - for (Iterator it = records.iterator(); it.hasNext(); ) { - Record record = (Record) it.next(); - maybeAddRecord(record); - } - if (!xfrin.isAXFR()) - throw new IllegalArgumentException("zones can only be " + - "created from AXFRs"); - validate(); -} - -/** - * Creates a Zone by doing the specified zone transfer. - * @param xfrin The incoming zone transfer to execute. - * @see ZoneTransferIn - */ -public -Zone(ZoneTransferIn xfrin) throws IOException, ZoneTransferException { - fromXFR(xfrin); -} - -/** - * Creates a Zone by performing a zone transfer to the specified host. - * @see ZoneTransferIn - */ -public -Zone(Name zone, int dclass, String remote) -throws IOException, ZoneTransferException -{ - ZoneTransferIn xfrin = ZoneTransferIn.newAXFR(zone, remote, null); - xfrin.setDClass(dclass); - fromXFR(xfrin); -} - -/** Returns the Zone's origin */ -public Name -getOrigin() { - return origin; -} - -/** Returns the Zone origin's NS records */ -public RRset -getNS() { - return NS; -} - -/** Returns the Zone's SOA record */ -public SOARecord -getSOA() { - return SOA; -} - -/** Returns the Zone's class */ -public int -getDClass() { - return dclass; -} - -private synchronized Object -exactName(Name name) { - return data.get(name); -} - -private synchronized RRset [] -allRRsets(Object types) { - if (types instanceof List) { - List typelist = (List) types; - return (RRset []) typelist.toArray(new RRset[typelist.size()]); - } else { - RRset set = (RRset) types; - return new RRset [] {set}; - } -} - -private synchronized RRset -oneRRset(Object types, int type) { - if (type == Type.ANY) - throw new IllegalArgumentException("oneRRset(ANY)"); - if (types instanceof List) { - List list = (List) types; - for (int i = 0; i < list.size(); i++) { - RRset set = (RRset) list.get(i); - if (set.getType() == type) - return set; - } - } else { - RRset set = (RRset) types; - if (set.getType() == type) - return set; - } - return null; -} - -private synchronized RRset -findRRset(Name name, int type) { - Object types = exactName(name); - if (types == null) - return null; - return oneRRset(types, type); -} - -private synchronized void -addRRset(Name name, RRset rrset) { - if (!hasWild && name.isWild()) - hasWild = true; - Object types = data.get(name); - if (types == null) { - data.put(name, rrset); - return; - } - int rtype = rrset.getType(); - if (types instanceof List) { - List list = (List) types; - for (int i = 0; i < list.size(); i++) { - RRset set = (RRset) list.get(i); - if (set.getType() == rtype) { - list.set(i, rrset); - return; - } - } - list.add(rrset); - } else { - RRset set = (RRset) types; - if (set.getType() == rtype) - data.put(name, rrset); - else { - LinkedList list = new LinkedList(); - list.add(set); - list.add(rrset); - data.put(name, list); - } - } -} - -private synchronized void -removeRRset(Name name, int type) { - Object types = data.get(name); - if (types == null) { - return; - } - if (types instanceof List) { - List list = (List) types; - for (int i = 0; i < list.size(); i++) { - RRset set = (RRset) list.get(i); - if (set.getType() == type) { - list.remove(i); - if (list.size() == 0) - data.remove(name); - return; - } - } - } else { - RRset set = (RRset) types; - if (set.getType() != type) - return; - data.remove(name); - } -} - -private synchronized SetResponse -lookup(Name name, int type) { - int labels; - int olabels; - int tlabels; - RRset rrset; - Name tname; - Object types; - SetResponse sr; - - if (!name.subdomain(origin)) - return SetResponse.ofType(SetResponse.NXDOMAIN); - - labels = name.labels(); - olabels = origin.labels(); - - for (tlabels = olabels; tlabels <= labels; tlabels++) { - boolean isOrigin = (tlabels == olabels); - boolean isExact = (tlabels == labels); - - if (isOrigin) - tname = origin; - else if (isExact) - tname = name; - else - tname = new Name(name, labels - tlabels); - - types = exactName(tname); - if (types == null) - continue; - - /* If this is a delegation, return that. */ - if (!isOrigin) { - RRset ns = oneRRset(types, Type.NS); - if (ns != null) - return new SetResponse(SetResponse.DELEGATION, - ns); - } - - /* If this is an ANY lookup, return everything. */ - if (isExact && type == Type.ANY) { - sr = new SetResponse(SetResponse.SUCCESSFUL); - RRset [] sets = allRRsets(types); - for (int i = 0; i < sets.length; i++) - sr.addRRset(sets[i]); - return sr; - } - - /* - * If this is the name, look for the actual type or a CNAME. - * Otherwise, look for a DNAME. - */ - if (isExact) { - rrset = oneRRset(types, type); - if (rrset != null) { - sr = new SetResponse(SetResponse.SUCCESSFUL); - sr.addRRset(rrset); - return sr; - } - rrset = oneRRset(types, Type.CNAME); - if (rrset != null) - return new SetResponse(SetResponse.CNAME, - rrset); - } else { - rrset = oneRRset(types, Type.DNAME); - if (rrset != null) - return new SetResponse(SetResponse.DNAME, - rrset); - } - - /* We found the name, but not the type. */ - if (isExact) - return SetResponse.ofType(SetResponse.NXRRSET); - } - - if (hasWild) { - for (int i = 0; i < labels - olabels; i++) { - tname = name.wild(i + 1); - - types = exactName(tname); - if (types == null) - continue; - - rrset = oneRRset(types, type); - if (rrset != null) { - sr = new SetResponse(SetResponse.SUCCESSFUL); - sr.addRRset(rrset); - return sr; - } - } - } - - return SetResponse.ofType(SetResponse.NXDOMAIN); -} - -/** - * Looks up Records in the Zone. This follows CNAMEs and wildcards. - * @param name The name to look up - * @param type The type to look up - * @return A SetResponse object - * @see SetResponse - */ -public SetResponse -findRecords(Name name, int type) { - return lookup(name, type); -} - -/** - * Looks up Records in the zone, finding exact matches only. - * @param name The name to look up - * @param type The type to look up - * @return The matching RRset - * @see RRset - */ -public RRset -findExactMatch(Name name, int type) { - Object types = exactName(name); - if (types == null) - return null; - return oneRRset(types, type); -} - -/** - * Adds an RRset to the Zone - * @param rrset The RRset to be added - * @see RRset - */ -public void -addRRset(RRset rrset) { - Name name = rrset.getName(); - addRRset(name, rrset); -} - -/** - * Adds a Record to the Zone - * @param r The record to be added - * @see Record - */ -public void -addRecord(Record r) { - Name name = r.getName(); - int rtype = r.getRRsetType(); - synchronized (this) { - RRset rrset = findRRset(name, rtype); - if (rrset == null) { - rrset = new RRset(r); - addRRset(name, rrset); - } else { - rrset.addRR(r); - } - } -} - -/** - * Removes a record from the Zone - * @param r The record to be removed - * @see Record - */ -public void -removeRecord(Record r) { - Name name = r.getName(); - int rtype = r.getRRsetType(); - synchronized (this) { - RRset rrset = findRRset(name, rtype); - if (rrset == null) - return; - if (rrset.size() == 1 && rrset.first().equals(r)) - removeRRset(name, rtype); - else - rrset.deleteRR(r); - } -} - -/** - * Returns an Iterator over the RRsets in the zone. - */ -public Iterator -iterator() { - return new ZoneIterator(false); -} - -/** - * Returns an Iterator over the RRsets in the zone that can be used to - * construct an AXFR response. This is identical to {@link #iterator} except - * that the SOA is returned at the end as well as the beginning. - */ -public Iterator -AXFR() { - return new ZoneIterator(true); -} - -private void -nodeToString(StringBuffer sb, Object node) { - RRset [] sets = allRRsets(node); - for (int i = 0; i < sets.length; i++) { - RRset rrset = sets[i]; - Iterator it = rrset.rrs(); - while (it.hasNext()) - sb.append(it.next() + "\n"); - it = rrset.sigs(); - while (it.hasNext()) - sb.append(it.next() + "\n"); - } -} - -/** - * Returns the contents of the Zone in master file format. - */ -public synchronized String -toMasterFile() { - Iterator zentries = data.entrySet().iterator(); - StringBuffer sb = new StringBuffer(); - nodeToString(sb, originNode); - while (zentries.hasNext()) { - Map.Entry entry = (Map.Entry) zentries.next(); - if (!origin.equals(entry.getKey())) - nodeToString(sb, entry.getValue()); - } - return sb.toString(); -} - -/** - * Returns the contents of the Zone as a string (in master file format). - */ -public String -toString() { - return toMasterFile(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/ZoneTransferException.java b/src/main/java/core/org/xbill/DNS/ZoneTransferException.java deleted file mode 100644 index 3ba487b4..00000000 --- a/src/main/java/core/org/xbill/DNS/ZoneTransferException.java +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS; - -/** - * An exception thrown when a zone transfer fails. - * - * @author Brian Wellington - */ - -public class ZoneTransferException extends Exception { - -public -ZoneTransferException() { - super(); -} - -public -ZoneTransferException(String s) { - super(s); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/ZoneTransferIn.java b/src/main/java/core/org/xbill/DNS/ZoneTransferIn.java deleted file mode 100644 index 3dbac874..00000000 --- a/src/main/java/core/org/xbill/DNS/ZoneTransferIn.java +++ /dev/null @@ -1,678 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) -// Parts of this are derived from lib/dns/xfrin.c from BIND 9; its copyright -// notice follows. - -/* - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package org.xbill.DNS; - -import java.io.*; -import java.net.*; -import java.util.*; - -/** - * An incoming DNS Zone Transfer. To use this class, first initialize an - * object, then call the run() method. If run() doesn't throw an exception - * the result will either be an IXFR-style response, an AXFR-style response, - * or an indication that the zone is up to date. - * - * @author Brian Wellington - */ - -public class ZoneTransferIn { - -private static final int INITIALSOA = 0; -private static final int FIRSTDATA = 1; -private static final int IXFR_DELSOA = 2; -private static final int IXFR_DEL = 3; -private static final int IXFR_ADDSOA = 4; -private static final int IXFR_ADD = 5; -private static final int AXFR = 6; -private static final int END = 7; - -private Name zname; -private int qtype; -private int dclass; -private long ixfr_serial; -private boolean want_fallback; -private ZoneTransferHandler handler; - -private SocketAddress localAddress; -private SocketAddress address; -private TCPClient client; -private TSIG tsig; -private TSIG.StreamVerifier verifier; -private long timeout = 900 * 1000; - -private int state; -private long end_serial; -private long current_serial; -private Record initialsoa; - -private int rtype; - -public static class Delta { - /** - * All changes between two versions of a zone in an IXFR response. - */ - - /** The starting serial number of this delta. */ - public long start; - - /** The ending serial number of this delta. */ - public long end; - - /** A list of records added between the start and end versions */ - public List adds; - - /** A list of records deleted between the start and end versions */ - public List deletes; - - private - Delta() { - adds = new ArrayList(); - deletes = new ArrayList(); - } -} - -public static interface ZoneTransferHandler { - /** - * Handles a Zone Transfer. - */ - - /** - * Called when an AXFR transfer begins. - */ - public void startAXFR() throws ZoneTransferException; - - /** - * Called when an IXFR transfer begins. - */ - public void startIXFR() throws ZoneTransferException; - - /** - * Called when a series of IXFR deletions begins. - * @param soa The starting SOA. - */ - public void startIXFRDeletes(Record soa) throws ZoneTransferException; - - /** - * Called when a series of IXFR adds begins. - * @param soa The starting SOA. - */ - public void startIXFRAdds(Record soa) throws ZoneTransferException; - - /** - * Called for each content record in an AXFR. - * @param r The DNS record. - */ - public void handleRecord(Record r) throws ZoneTransferException; -}; - -private static class BasicHandler implements ZoneTransferHandler { - private List axfr; - private List ixfr; - - public void startAXFR() { - axfr = new ArrayList(); - } - - public void startIXFR() { - ixfr = new ArrayList(); - } - - public void startIXFRDeletes(Record soa) { - Delta delta = new Delta(); - delta.deletes.add(soa); - delta.start = getSOASerial(soa); - ixfr.add(delta); - } - - public void startIXFRAdds(Record soa) { - Delta delta = (Delta) ixfr.get(ixfr.size() - 1); - delta.adds.add(soa); - delta.end = getSOASerial(soa); - } - - public void handleRecord(Record r) { - List list; - if (ixfr != null) { - Delta delta = (Delta) ixfr.get(ixfr.size() - 1); - if (delta.adds.size() > 0) - list = delta.adds; - else - list = delta.deletes; - } else - list = axfr; - list.add(r); - } -}; - -private -ZoneTransferIn() {} - -private -ZoneTransferIn(Name zone, int xfrtype, long serial, boolean fallback, - SocketAddress address, TSIG key) -{ - this.address = address; - this.tsig = key; - if (zone.isAbsolute()) - zname = zone; - else { - try { - zname = Name.concatenate(zone, Name.root); - } - catch (NameTooLongException e) { - throw new IllegalArgumentException("ZoneTransferIn: " + - "name too long"); - } - } - qtype = xfrtype; - dclass = DClass.IN; - ixfr_serial = serial; - want_fallback = fallback; - state = INITIALSOA; -} - -/** - * Instantiates a ZoneTransferIn object to do an AXFR (full zone transfer). - * @param zone The zone to transfer. - * @param address The host/port from which to transfer the zone. - * @param key The TSIG key used to authenticate the transfer, or null. - * @return The ZoneTransferIn object. - */ -public static ZoneTransferIn -newAXFR(Name zone, SocketAddress address, TSIG key) { - return new ZoneTransferIn(zone, Type.AXFR, 0, false, address, key); -} - -/** - * Instantiates a ZoneTransferIn object to do an AXFR (full zone transfer). - * @param zone The zone to transfer. - * @param host The host from which to transfer the zone. - * @param port The port to connect to on the server, or 0 for the default. - * @param key The TSIG key used to authenticate the transfer, or null. - * @return The ZoneTransferIn object. - * @throws UnknownHostException The host does not exist. - */ -public static ZoneTransferIn -newAXFR(Name zone, String host, int port, TSIG key) -throws UnknownHostException -{ - if (port == 0) - port = SimpleResolver.DEFAULT_PORT; - return newAXFR(zone, new InetSocketAddress(host, port), key); -} - -/** - * Instantiates a ZoneTransferIn object to do an AXFR (full zone transfer). - * @param zone The zone to transfer. - * @param host The host from which to transfer the zone. - * @param key The TSIG key used to authenticate the transfer, or null. - * @return The ZoneTransferIn object. - * @throws UnknownHostException The host does not exist. - */ -public static ZoneTransferIn -newAXFR(Name zone, String host, TSIG key) -throws UnknownHostException -{ - return newAXFR(zone, host, 0, key); -} - -/** - * Instantiates a ZoneTransferIn object to do an IXFR (incremental zone - * transfer). - * @param zone The zone to transfer. - * @param serial The existing serial number. - * @param fallback If true, fall back to AXFR if IXFR is not supported. - * @param address The host/port from which to transfer the zone. - * @param key The TSIG key used to authenticate the transfer, or null. - * @return The ZoneTransferIn object. - */ -public static ZoneTransferIn -newIXFR(Name zone, long serial, boolean fallback, SocketAddress address, - TSIG key) -{ - return new ZoneTransferIn(zone, Type.IXFR, serial, fallback, address, - key); -} - -/** - * Instantiates a ZoneTransferIn object to do an IXFR (incremental zone - * transfer). - * @param zone The zone to transfer. - * @param serial The existing serial number. - * @param fallback If true, fall back to AXFR if IXFR is not supported. - * @param host The host from which to transfer the zone. - * @param port The port to connect to on the server, or 0 for the default. - * @param key The TSIG key used to authenticate the transfer, or null. - * @return The ZoneTransferIn object. - * @throws UnknownHostException The host does not exist. - */ -public static ZoneTransferIn -newIXFR(Name zone, long serial, boolean fallback, String host, int port, - TSIG key) -throws UnknownHostException -{ - if (port == 0) - port = SimpleResolver.DEFAULT_PORT; - return newIXFR(zone, serial, fallback, - new InetSocketAddress(host, port), key); -} - -/** - * Instantiates a ZoneTransferIn object to do an IXFR (incremental zone - * transfer). - * @param zone The zone to transfer. - * @param serial The existing serial number. - * @param fallback If true, fall back to AXFR if IXFR is not supported. - * @param host The host from which to transfer the zone. - * @param key The TSIG key used to authenticate the transfer, or null. - * @return The ZoneTransferIn object. - * @throws UnknownHostException The host does not exist. - */ -public static ZoneTransferIn -newIXFR(Name zone, long serial, boolean fallback, String host, TSIG key) -throws UnknownHostException -{ - return newIXFR(zone, serial, fallback, host, 0, key); -} - -/** - * Gets the name of the zone being transferred. - */ -public Name -getName() { - return zname; -} - -/** - * Gets the type of zone transfer (either AXFR or IXFR). - */ -public int -getType() { - return qtype; -} - -/** - * Sets a timeout on this zone transfer. The default is 900 seconds (15 - * minutes). - * @param secs The maximum amount of time that this zone transfer can take. - */ -public void -setTimeout(int secs) { - if (secs < 0) - throw new IllegalArgumentException("timeout cannot be " + - "negative"); - timeout = 1000L * secs; -} - -/** - * Sets an alternate DNS class for this zone transfer. - * @param dclass The class to use instead of class IN. - */ -public void -setDClass(int dclass) { - DClass.check(dclass); - this.dclass = dclass; -} - -/** - * Sets the local address to bind to when sending messages. - * @param addr The local address to send messages from. - */ -public void -setLocalAddress(SocketAddress addr) { - this.localAddress = addr; -} - -private void -openConnection() throws IOException { - long endTime = System.currentTimeMillis() + timeout; - client = new TCPClient(endTime); - if (localAddress != null) - client.bind(localAddress); - client.connect(address); -} - -private void -sendQuery() throws IOException { - Record question = Record.newRecord(zname, qtype, dclass); - - Message query = new Message(); - query.getHeader().setOpcode(Opcode.QUERY); - query.addRecord(question, Section.QUESTION); - if (qtype == Type.IXFR) { - Record soa = new SOARecord(zname, dclass, 0, Name.root, - Name.root, ixfr_serial, - 0, 0, 0, 0); - query.addRecord(soa, Section.AUTHORITY); - } - if (tsig != null) { - tsig.apply(query, null); - verifier = new TSIG.StreamVerifier(tsig, query.getTSIG()); - } - byte [] out = query.toWire(Message.MAXLENGTH); - client.send(out); -} - -private static long -getSOASerial(Record rec) { - SOARecord soa = (SOARecord) rec; - return soa.getSerial(); -} - -private void -logxfr(String s) { - if (Options.check("verbose")) - System.out.println(zname + ": " + s); -} - -private void -fail(String s) throws ZoneTransferException { - throw new ZoneTransferException(s); -} - -private void -fallback() throws ZoneTransferException { - if (!want_fallback) - fail("server doesn't support IXFR"); - - logxfr("falling back to AXFR"); - qtype = Type.AXFR; - state = INITIALSOA; -} - -private void -parseRR(Record rec) throws ZoneTransferException { - int type = rec.getType(); - Delta delta; - - switch (state) { - case INITIALSOA: - if (type != Type.SOA) - fail("missing initial SOA"); - initialsoa = rec; - // Remember the serial number in the initial SOA; we need it - // to recognize the end of an IXFR. - end_serial = getSOASerial(rec); - if (qtype == Type.IXFR && - Serial.compare(end_serial, ixfr_serial) <= 0) - { - logxfr("up to date"); - state = END; - break; - } - state = FIRSTDATA; - break; - - case FIRSTDATA: - // If the transfer begins with 1 SOA, it's an AXFR. - // If it begins with 2 SOAs, it's an IXFR. - if (qtype == Type.IXFR && type == Type.SOA && - getSOASerial(rec) == ixfr_serial) - { - rtype = Type.IXFR; - handler.startIXFR(); - logxfr("got incremental response"); - state = IXFR_DELSOA; - } else { - rtype = Type.AXFR; - handler.startAXFR(); - handler.handleRecord(initialsoa); - logxfr("got nonincremental response"); - state = AXFR; - } - parseRR(rec); // Restart... - return; - - case IXFR_DELSOA: - handler.startIXFRDeletes(rec); - state = IXFR_DEL; - break; - - case IXFR_DEL: - if (type == Type.SOA) { - current_serial = getSOASerial(rec); - state = IXFR_ADDSOA; - parseRR(rec); // Restart... - return; - } - handler.handleRecord(rec); - break; - - case IXFR_ADDSOA: - handler.startIXFRAdds(rec); - state = IXFR_ADD; - break; - - case IXFR_ADD: - if (type == Type.SOA) { - long soa_serial = getSOASerial(rec); - if (soa_serial == end_serial) { - state = END; - break; - } else if (soa_serial != current_serial) { - fail("IXFR out of sync: expected serial " + - current_serial + " , got " + soa_serial); - } else { - state = IXFR_DELSOA; - parseRR(rec); // Restart... - return; - } - } - handler.handleRecord(rec); - break; - - case AXFR: - // Old BINDs sent cross class A records for non IN classes. - if (type == Type.A && rec.getDClass() != dclass) - break; - handler.handleRecord(rec); - if (type == Type.SOA) { - state = END; - } - break; - - case END: - fail("extra data"); - break; - - default: - fail("invalid state"); - break; - } -} - -private void -closeConnection() { - try { - if (client != null) - client.cleanup(); - } - catch (IOException e) { - } -} - -private Message -parseMessage(byte [] b) throws WireParseException { - try { - return new Message(b); - } - catch (IOException e) { - if (e instanceof WireParseException) - throw (WireParseException) e; - throw new WireParseException("Error parsing message"); - } -} - -private void -doxfr() throws IOException, ZoneTransferException { - sendQuery(); - while (state != END) { - byte [] in = client.recv(); - Message response = parseMessage(in); - if (response.getHeader().getRcode() == Rcode.NOERROR && - verifier != null) - { - TSIGRecord tsigrec = response.getTSIG(); - - int error = verifier.verify(response, in); - if (error != Rcode.NOERROR) - fail("TSIG failure"); - } - - Record [] answers = response.getSectionArray(Section.ANSWER); - - if (state == INITIALSOA) { - int rcode = response.getRcode(); - if (rcode != Rcode.NOERROR) { - if (qtype == Type.IXFR && - rcode == Rcode.NOTIMP) - { - fallback(); - doxfr(); - return; - } - fail(Rcode.string(rcode)); - } - - Record question = response.getQuestion(); - if (question != null && question.getType() != qtype) { - fail("invalid question section"); - } - - if (answers.length == 0 && qtype == Type.IXFR) { - fallback(); - doxfr(); - return; - } - } - - for (int i = 0; i < answers.length; i++) { - parseRR(answers[i]); - } - - if (state == END && verifier != null && - !response.isVerified()) - fail("last message must be signed"); - } -} - -/** - * Does the zone transfer. - * @param handler The callback object that handles the zone transfer data. - * @throws IOException The zone transfer failed to due an IO problem. - * @throws ZoneTransferException The zone transfer failed to due a problem - * with the zone transfer itself. - */ -public void -run(ZoneTransferHandler handler) throws IOException, ZoneTransferException { - this.handler = handler; - try { - openConnection(); - doxfr(); - } - finally { - closeConnection(); - } -} - -/** - * Does the zone transfer. - * @return A list, which is either an AXFR-style response (List of Records), - * and IXFR-style response (List of Deltas), or null, which indicates that - * an IXFR was performed and the zone is up to date. - * @throws IOException The zone transfer failed to due an IO problem. - * @throws ZoneTransferException The zone transfer failed to due a problem - * with the zone transfer itself. - */ -public List -run() throws IOException, ZoneTransferException { - BasicHandler handler = new BasicHandler(); - run(handler); - if (handler.axfr != null) - return handler.axfr; - return handler.ixfr; -} - -private BasicHandler -getBasicHandler() throws IllegalArgumentException { - if (handler instanceof BasicHandler) - return (BasicHandler) handler; - throw new IllegalArgumentException("ZoneTransferIn used callback " + - "interface"); -} - -/** - * Returns true if the response is an AXFR-style response (List of Records). - * This will be true if either an IXFR was performed, an IXFR was performed - * and the server provided a full zone transfer, or an IXFR failed and - * fallback to AXFR occurred. - */ -public boolean -isAXFR() { - return (rtype == Type.AXFR); -} - -/** - * Gets the AXFR-style response. - * @throws IllegalArgumentException The transfer used the callback interface, - * so the response was not stored. - */ -public List -getAXFR() { - BasicHandler handler = getBasicHandler(); - return handler.axfr; -} - -/** - * Returns true if the response is an IXFR-style response (List of Deltas). - * This will be true only if an IXFR was performed and the server provided - * an incremental zone transfer. - */ -public boolean -isIXFR() { - return (rtype == Type.IXFR); -} - -/** - * Gets the IXFR-style response. - * @throws IllegalArgumentException The transfer used the callback interface, - * so the response was not stored. - */ -public List -getIXFR() { - BasicHandler handler = getBasicHandler(); - return handler.ixfr; -} - -/** - * Returns true if the response indicates that the zone is up to date. - * This will be true only if an IXFR was performed. - * @throws IllegalArgumentException The transfer used the callback interface, - * so the response was not stored. - */ -public boolean -isCurrent() { - BasicHandler handler = getBasicHandler(); - return (handler.axfr == null && handler.ixfr == null); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/jnamed.java b/src/main/java/core/org/xbill/DNS/jnamed.java deleted file mode 100644 index 3cc4ab1e..00000000 --- a/src/main/java/core/org/xbill/DNS/jnamed.java +++ /dev/null @@ -1,599 +0,0 @@ -package org.xbill.DNS; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** @author Brian Wellington <bwelling@xbill.org> */ - -public class jnamed { - -static final int FLAG_DNSSECOK = 1; -static final int FLAG_SIGONLY = 2; - -Map caches; -Map znames; -Map TSIGs; -String spoofIP = null; -Record answer = null; -Record[] answers = null; - -private static String -addrport(InetAddress addr, int port) { - return addr.getHostAddress() + "#" + port; -} - -public -jnamed() throws IOException, ZoneTransferException { - caches = new HashMap(); - znames = new HashMap(); - TSIGs = new HashMap(); -} - -public -jnamed(String ip) throws IOException { - caches = new HashMap(); - znames = new HashMap(); - TSIGs = new HashMap(); - this.spoofIP = ip; -} - -public -jnamed(Record answer) throws IOException { - caches = new HashMap(); - znames = new HashMap(); - TSIGs = new HashMap(); - this.answer = answer; -} - -public -jnamed(Record[] answers) { - caches = new HashMap(); - znames = new HashMap(); - TSIGs = new HashMap(); - this.answers = answers; -} - -public void -addPrimaryZone(String zname, String zonefile) throws IOException { - Name origin = null; - if (zname != null) - origin = Name.fromString(zname, Name.root); - Zone newzone = new Zone(origin, zonefile); - znames.put(newzone.getOrigin(), newzone); -} - -public void -addSecondaryZone(String zone, String remote) -throws IOException, ZoneTransferException -{ - Name zname = Name.fromString(zone, Name.root); - Zone newzone = new Zone(zname, DClass.IN, remote); - znames.put(zname, newzone); -} - -public void -addTSIG(String algstr, String namestr, String key) throws IOException { - Name name = Name.fromString(namestr, Name.root); - TSIGs.put(name, new TSIG(algstr, namestr, key)); -} - -public Cache -getCache(int dclass) { - Cache c = (Cache) caches.get(dclass); - if (c == null) { - c = new Cache(dclass); - caches.put(dclass, c); - } - return c; -} - -public Zone -findBestZone(Name name) { - Zone foundzone = null; - foundzone = (Zone) znames.get(name); - if (foundzone != null) - return foundzone; - int labels = name.labels(); - for (int i = 1; i < labels; i++) { - Name tname = new Name(name, i); - foundzone = (Zone) znames.get(tname); - if (foundzone != null) - return foundzone; - } - return null; -} - -public RRset -findExactMatch(Name name, int type, int dclass, boolean glue) { - Zone zone = findBestZone(name); - if (zone != null) - return zone.findExactMatch(name, type); - else { - RRset [] rrsets; - Cache cache = getCache(dclass); - if (glue) - rrsets = cache.findAnyRecords(name, type); - else - rrsets = cache.findRecords(name, type); - if (rrsets == null) - return null; - else - return rrsets[0]; /* not quite right */ - } -} - -void -addRRset(Name name, Message response, RRset rrset, int section, int flags) { - for (int s = 1; s <= section; s++) - if (response.findRRset(name, rrset.getType(), s)) - return; - if ((flags & FLAG_SIGONLY) == 0) { - Iterator it = rrset.rrs(); - while (it.hasNext()) { - Record r = (Record) it.next(); - if (r.getName().isWild() && !name.isWild()) - r = r.withName(name); - response.addRecord(r, section); - } - } - if ((flags & (FLAG_SIGONLY | FLAG_DNSSECOK)) != 0) { - Iterator it = rrset.sigs(); - while (it.hasNext()) { - Record r = (Record) it.next(); - if (r.getName().isWild() && !name.isWild()) - r = r.withName(name); - response.addRecord(r, section); - } - } -} - -private final void -addSOA(Message response, Zone zone) { - response.addRecord(zone.getSOA(), Section.AUTHORITY); -} - -private final void -addNS(Message response, Zone zone, int flags) { - RRset nsRecords = zone.getNS(); - addRRset(nsRecords.getName(), response, nsRecords, - Section.AUTHORITY, flags); -} - -private final void -addCacheNS(Message response, Cache cache, Name name) { - SetResponse sr = cache.lookupRecords(name, Type.NS, Credibility.HINT); - if (!sr.isDelegation()) - return; - RRset nsRecords = sr.getNS(); - Iterator it = nsRecords.rrs(); - while (it.hasNext()) { - Record r = (Record) it.next(); - response.addRecord(r, Section.AUTHORITY); - } -} - -private void -addGlue(Message response, Name name, int flags) { - RRset a = findExactMatch(name, Type.A, DClass.IN, true); - if (a == null) - return; - addRRset(name, response, a, Section.ADDITIONAL, flags); -} - -private void -addAdditional2(Message response, int section, int flags) { - Record [] records = response.getSectionArray(section); - for (int i = 0; i < records.length; i++) { - Record r = records[i]; - Name glueName = r.getAdditionalName(); - if (glueName != null) - addGlue(response, glueName, flags); - } -} - -private final void -addAdditional(Message response, int flags) { - addAdditional2(response, Section.ANSWER, flags); - addAdditional2(response, Section.AUTHORITY, flags); -} - -byte -addAnswer(Message response, Name name, int type, int dclass, - int iterations, int flags) -{ - SetResponse sr; - byte rcode = Rcode.NOERROR; - - if (iterations > 6) - return Rcode.NOERROR; - - if (type == Type.SIG || type == Type.RRSIG) { - type = Type.ANY; - flags |= FLAG_SIGONLY; - } - - Zone zone = findBestZone(name); - if (zone != null) - sr = zone.findRecords(name, type); - else { - Cache cache = getCache(dclass); - sr = cache.lookupRecords(name, type, Credibility.NORMAL); - } - - if (sr.isUnknown()) { - addCacheNS(response, getCache(dclass), name); - } - if (sr.isNXDOMAIN()) { - response.getHeader().setRcode(Rcode.NXDOMAIN); - if (zone != null) { - addSOA(response, zone); - if (iterations == 0) - response.getHeader().setFlag(Flags.AA); - } - rcode = Rcode.NXDOMAIN; - } - else if (sr.isNXRRSET()) { - if (zone != null) { - addSOA(response, zone); - if (iterations == 0) - response.getHeader().setFlag(Flags.AA); - } - } - else if (sr.isDelegation()) { - RRset nsRecords = sr.getNS(); - addRRset(nsRecords.getName(), response, nsRecords, - Section.AUTHORITY, flags); - } - else if (sr.isCNAME()) { - CNAMERecord cname = sr.getCNAME(); - RRset rrset = new RRset(cname); - addRRset(name, response, rrset, Section.ANSWER, flags); - if (zone != null && iterations == 0) - response.getHeader().setFlag(Flags.AA); - rcode = addAnswer(response, cname.getTarget(), - type, dclass, iterations + 1, flags); - } - else if (sr.isDNAME()) { - DNAMERecord dname = sr.getDNAME(); - RRset rrset = new RRset(dname); - addRRset(name, response, rrset, Section.ANSWER, flags); - Name newname; - try { - newname = name.fromDNAME(dname); - } - catch (NameTooLongException e) { - return Rcode.YXDOMAIN; - } - rrset = new RRset(new CNAMERecord(name, dclass, 0, newname)); - addRRset(name, response, rrset, Section.ANSWER, flags); - if (zone != null && iterations == 0) - response.getHeader().setFlag(Flags.AA); - rcode = addAnswer(response, newname, type, dclass, - iterations + 1, flags); - } - else if (sr.isSuccessful()) { - RRset [] rrsets = sr.answers(); - for (int i = 0; i < rrsets.length; i++) - addRRset(name, response, rrsets[i], - Section.ANSWER, flags); - if (zone != null) { - addNS(response, zone, flags); - if (iterations == 0) - response.getHeader().setFlag(Flags.AA); - } - else - addCacheNS(response, getCache(dclass), name); - } - - try { - if (this.answer != null) { - addRRset(name, response, new RRset(this.answer), Section.ANSWER, flags); - } - if (this.answers != null) { - for (Record record : this.answers) { - addRRset(name, response, new RRset(record), Section.ANSWER, flags); - } - } - if (this.spoofIP != null) { - RRset rrset; - if(type == 1){ - rrset = new RRset(new ARecord(name, dclass, 0, InetAddress.getByName(this.spoofIP))); - } else { - rrset = new RRset(new AAAARecord(name, dclass, 0, InetAddress.getByName(this.spoofIP))); - } - addRRset(name, response, rrset, Section.ANSWER, flags); - } - } catch (Exception e) { - e.printStackTrace(); - } - - return rcode; -} - -byte [] -doAXFR(Name name, Message query, TSIG tsig, TSIGRecord qtsig, Socket s) { - Zone zone = (Zone) znames.get(name); - boolean first = true; - if (zone == null) - return errorMessage(query, Rcode.REFUSED); - Iterator it = zone.AXFR(); - try { - DataOutputStream dataOut; - dataOut = new DataOutputStream(s.getOutputStream()); - int id = query.getHeader().getID(); - while (it.hasNext()) { - RRset rrset = (RRset) it.next(); - Message response = new Message(id); - Header header = response.getHeader(); - header.setFlag(Flags.QR); - header.setFlag(Flags.AA); - addRRset(rrset.getName(), response, rrset, - Section.ANSWER, FLAG_DNSSECOK); - if (tsig != null) { - tsig.applyStream(response, qtsig, first); - qtsig = response.getTSIG(); - } - first = false; - byte [] out = response.toWire(); - dataOut.writeShort(out.length); - dataOut.write(out); - } - } - catch (IOException ex) { - System.out.println("AXFR failed"); - } - try { - s.close(); - } - catch (IOException ex) { - } - return null; -} - -/* - * Note: a null return value means that the caller doesn't need to do - * anything. Currently this only happens if this is an AXFR request over - * TCP. - */ -public byte [] -generateReply(Message query, byte [] in, int length, Socket s) -throws IOException -{ - Header header; - boolean badversion; - int maxLength; - int flags = 0; - - header = query.getHeader(); - if (header.getFlag(Flags.QR)) - return null; - if (header.getRcode() != Rcode.NOERROR) - return errorMessage(query, Rcode.FORMERR); - if (header.getOpcode() != Opcode.QUERY) - return errorMessage(query, Rcode.NOTIMP); - - Record queryRecord = query.getQuestion(); - - - TSIGRecord queryTSIG = query.getTSIG(); - TSIG tsig = null; - if (queryTSIG != null) { - tsig = (TSIG) TSIGs.get(queryTSIG.getName()); - if (tsig == null || - tsig.verify(query, in, length, null) != Rcode.NOERROR) - return formerrMessage(in); - } - - OPTRecord queryOPT = query.getOPT(); - if (queryOPT != null && queryOPT.getVersion() > 0) - badversion = true; - - if (s != null) - maxLength = 65535; - else if (queryOPT != null) - maxLength = Math.max(queryOPT.getPayloadSize(), 512); - else - maxLength = 512; - - if (queryOPT != null && (queryOPT.getFlags() & ExtendedFlags.DO) != 0) - flags = FLAG_DNSSECOK; - - Message response = new Message(query.getHeader().getID()); - response.getHeader().setFlag(Flags.QR); - if (query.getHeader().getFlag(Flags.RD)) - response.getHeader().setFlag(Flags.RD); - response.addRecord(queryRecord, Section.QUESTION); - - Name name = queryRecord.getName(); - int type = queryRecord.getType(); - int dclass = queryRecord.getDClass(); - if (type == Type.AXFR && s != null) - return doAXFR(name, query, tsig, queryTSIG, s); - if (!Type.isRR(type) && type != Type.ANY) - return errorMessage(query, Rcode.NOTIMP); - - byte rcode = addAnswer(response, name, type, dclass, 0, flags); - if (rcode != Rcode.NOERROR && rcode != Rcode.NXDOMAIN) - return errorMessage(query, rcode); - - addAdditional(response, flags); - - if (queryOPT != null) { - int optflags = (flags == FLAG_DNSSECOK) ? ExtendedFlags.DO : 0; - OPTRecord opt = new OPTRecord((short)4096, rcode, (byte)0, - optflags); - response.addRecord(opt, Section.ADDITIONAL); - } - - response.setTSIG(tsig, Rcode.NOERROR, queryTSIG); - return response.toWire(maxLength); -} - -byte [] -buildErrorMessage(Header header, int rcode, Record question) { - Message response = new Message(); - response.setHeader(header); - for (int i = 0; i < 4; i++) - response.removeAllRecords(i); - if (rcode == Rcode.SERVFAIL) - response.addRecord(question, Section.QUESTION); - header.setRcode(rcode); - return response.toWire(); -} - -public byte [] -formerrMessage(byte [] in) { - Header header; - try { - header = new Header(in); - } - catch (IOException e) { - return null; - } - return buildErrorMessage(header, Rcode.FORMERR, null); -} - -public byte [] -errorMessage(Message query, int rcode) { - return buildErrorMessage(query.getHeader(), rcode, - query.getQuestion()); -} - -public void -TCPclient(Socket s) { - try { - int inLength; - DataInputStream dataIn; - DataOutputStream dataOut; - byte [] in; - - InputStream is = s.getInputStream(); - dataIn = new DataInputStream(is); - inLength = dataIn.readUnsignedShort(); - in = new byte[inLength]; - dataIn.readFully(in); - - Message query; - byte [] response = null; - try { - query = new Message(in); - response = generateReply(query, in, in.length, s); - if (response == null) - return; - } - catch (IOException e) { - response = formerrMessage(in); - } - dataOut = new DataOutputStream(s.getOutputStream()); - dataOut.writeShort(response.length); - dataOut.write(response); - } - catch (IOException e) { - System.out.println("TCPclient(" + - addrport(s.getLocalAddress(), - s.getLocalPort()) + - "): " + e); - } - finally { - try { - s.close(); - } - catch (IOException e) {} - } -} - -public void -serveTCP(InetAddress addr, int port) { - try { - ServerSocket sock = new ServerSocket(port, 128, addr); - while (true) { - final Socket s = sock.accept(); - Thread t; - t = new Thread(new Runnable() { - public void run() {TCPclient(s);}}); - t.start(); - } - } - catch (IOException e) { - System.out.println("serveTCP(" + addrport(addr, port) + "): " + - e); - } -} - -public void -serveUDP(InetAddress addr, int port) { - try { - DatagramSocket sock = new DatagramSocket(port, addr); - final short udpLength = 512; - byte [] in = new byte[udpLength]; - DatagramPacket indp = new DatagramPacket(in, in.length); - DatagramPacket outdp = null; - while (true) { - indp.setLength(in.length); - try { - sock.receive(indp); - } - catch (InterruptedIOException e) { - continue; - } - Message query; - byte [] response = null; - try { - query = new Message(in); - response = generateReply(query, in, - indp.getLength(), - null); - if (response == null) - continue; - } - catch (IOException e) { - response = formerrMessage(in); - } - if (outdp == null) - outdp = new DatagramPacket(response, - response.length, - indp.getAddress(), - indp.getPort()); - else { - outdp.setData(response); - outdp.setLength(response.length); - outdp.setAddress(indp.getAddress()); - outdp.setPort(indp.getPort()); - } - sock.send(outdp); - } - } - catch (IOException e) { - System.out.println("serveUDP(" + addrport(addr, port) + "): " + - e); - } -} - -public void -addTCP(final InetAddress addr, final int port) { - Thread t; - t = new Thread(new Runnable() { - public void run() {serveTCP(addr, port);}}); - t.start(); -} - -public void -addUDP(final InetAddress addr, final int port) { - Thread t; - t = new Thread(new Runnable() { - public void run() {serveUDP(addr, port);}}); - t.start(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/utils/base16.java b/src/main/java/core/org/xbill/DNS/utils/base16.java deleted file mode 100644 index 58024e62..00000000 --- a/src/main/java/core/org/xbill/DNS/utils/base16.java +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS.utils; - -import java.io.*; - -/** - * Routines for converting between Strings of hex-encoded data and arrays of - * binary data. This is not actually used by DNS. - * - * @author Brian Wellington - */ - -public class base16 { - -private static final String Base16 = "0123456789ABCDEF"; - -private -base16() {} - -/** - * Convert binary data to a hex-encoded String - * @param b An array containing binary data - * @return A String containing the encoded data - */ -public static String -toString(byte [] b) { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - for (int i = 0; i < b.length; i++) { - short value = (short) (b[i] & 0xFF); - byte high = (byte) (value >> 4); - byte low = (byte) (value & 0xF); - os.write(Base16.charAt(high)); - os.write(Base16.charAt(low)); - } - return new String(os.toByteArray()); -} - -/** - * Convert a hex-encoded String to binary data - * @param str A String containing the encoded data - * @return An array containing the binary data, or null if the string is invalid - */ -public static byte [] -fromString(String str) { - ByteArrayOutputStream bs = new ByteArrayOutputStream(); - byte [] raw = str.getBytes(); - for (int i = 0; i < raw.length; i++) { - if (!Character.isWhitespace((char)raw[i])) - bs.write(raw[i]); - } - byte [] in = bs.toByteArray(); - if (in.length % 2 != 0) { - return null; - } - - bs.reset(); - DataOutputStream ds = new DataOutputStream(bs); - - for (int i = 0; i < in.length; i += 2) { - byte high = (byte) Base16.indexOf(Character.toUpperCase((char)in[i])); - byte low = (byte) Base16.indexOf(Character.toUpperCase((char)in[i+1])); - try { - ds.writeByte((high << 4) + low); - } - catch (IOException e) { - } - } - return bs.toByteArray(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/utils/base32.java b/src/main/java/core/org/xbill/DNS/utils/base32.java deleted file mode 100644 index a2f26eaa..00000000 --- a/src/main/java/core/org/xbill/DNS/utils/base32.java +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS.utils; - -import java.io.*; - -/** - * Routines for converting between Strings of base32-encoded data and arrays - * of binary data. This currently supports the base32 and base32hex alphabets - * specified in RFC 4648, sections 6 and 7. - * - * @author Brian Wellington - */ - -public class base32 { - -public static class Alphabet { - private Alphabet() {} - - public static final String BASE32 = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="; - public static final String BASE32HEX = - "0123456789ABCDEFGHIJKLMNOPQRSTUV="; -}; - -private String alphabet; -private boolean padding, lowercase; - -/** - * Creates an object that can be used to do base32 conversions. - * @param alphabet Which alphabet should be used - * @param padding Whether padding should be used - * @param lowercase Whether lowercase characters should be used. - * default parameters (The standard base32 alphabet, no padding, uppercase) - */ -public -base32(String alphabet, boolean padding, boolean lowercase) { - this.alphabet = alphabet; - this.padding = padding; - this.lowercase = lowercase; -} - -static private int -blockLenToPadding(int blocklen) { - switch (blocklen) { - case 1: - return 6; - case 2: - return 4; - case 3: - return 3; - case 4: - return 1; - case 5: - return 0; - default: - return -1; - } -} - -static private int -paddingToBlockLen(int padlen) { - switch (padlen) { - case 6: - return 1; - case 4: - return 2; - case 3: - return 3; - case 1: - return 4; - case 0: - return 5; - default : - return -1; - } -} - -/** - * Convert binary data to a base32-encoded String - * - * @param b An array containing binary data - * @return A String containing the encoded data - */ -public String -toString(byte [] b) { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - for (int i = 0; i < (b.length + 4) / 5; i++) { - short s[] = new short[5]; - int t[] = new int[8]; - - int blocklen = 5; - for (int j = 0; j < 5; j++) { - if ((i * 5 + j) < b.length) - s[j] = (short) (b[i * 5 + j] & 0xFF); - else { - s[j] = 0; - blocklen--; - } - } - int padlen = blockLenToPadding(blocklen); - - // convert the 5 byte block into 8 characters (values 0-31). - - // upper 5 bits from first byte - t[0] = (byte) ((s[0] >> 3) & 0x1F); - // lower 3 bits from 1st byte, upper 2 bits from 2nd. - t[1] = (byte) (((s[0] & 0x07) << 2) | ((s[1] >> 6) & 0x03)); - // bits 5-1 from 2nd. - t[2] = (byte) ((s[1] >> 1) & 0x1F); - // lower 1 bit from 2nd, upper 4 from 3rd - t[3] = (byte) (((s[1] & 0x01) << 4) | ((s[2] >> 4) & 0x0F)); - // lower 4 from 3rd, upper 1 from 4th. - t[4] = (byte) (((s[2] & 0x0F) << 1) | ((s[3] >> 7) & 0x01)); - // bits 6-2 from 4th - t[5] = (byte) ((s[3] >> 2) & 0x1F); - // lower 2 from 4th, upper 3 from 5th; - t[6] = (byte) (((s[3] & 0x03) << 3) | ((s[4] >> 5) & 0x07)); - // lower 5 from 5th; - t[7] = (byte) (s[4] & 0x1F); - - // write out the actual characters. - for (int j = 0; j < t.length - padlen; j++) { - char c = alphabet.charAt(t[j]); - if (lowercase) - c = Character.toLowerCase(c); - os.write(c); - } - - // write out the padding (if any) - if (padding) { - for (int j = t.length - padlen; j < t.length; j++) - os.write('='); - } - } - - return new String(os.toByteArray()); -} - -/** - * Convert a base32-encoded String to binary data - * - * @param str A String containing the encoded data - * @return An array containing the binary data, or null if the string is invalid - */ -public byte[] -fromString(String str) { - ByteArrayOutputStream bs = new ByteArrayOutputStream(); - byte [] raw = str.getBytes(); - for (int i = 0; i < raw.length; i++) - { - char c = (char) raw[i]; - if (!Character.isWhitespace(c)) { - c = Character.toUpperCase(c); - bs.write((byte) c); - } - } - - if (padding) { - if (bs.size() % 8 != 0) - return null; - } else { - while (bs.size() % 8 != 0) - bs.write('='); - } - - byte [] in = bs.toByteArray(); - - bs.reset(); - DataOutputStream ds = new DataOutputStream(bs); - - for (int i = 0; i < in.length / 8; i++) { - short[] s = new short[8]; - int[] t = new int[5]; - - int padlen = 8; - for (int j = 0; j < 8; j++) { - char c = (char) in[i * 8 + j]; - if (c == '=') - break; - s[j] = (short) alphabet.indexOf(in[i * 8 + j]); - if (s[j] < 0) - return null; - padlen--; - } - int blocklen = paddingToBlockLen(padlen); - if (blocklen < 0) - return null; - - // all 5 bits of 1st, high 3 (of 5) of 2nd - t[0] = (s[0] << 3) | s[1] >> 2; - // lower 2 of 2nd, all 5 of 3rd, high 1 of 4th - t[1] = ((s[1] & 0x03) << 6) | (s[2] << 1) | (s[3] >> 4); - // lower 4 of 4th, high 4 of 5th - t[2] = ((s[3] & 0x0F) << 4) | ((s[4] >> 1) & 0x0F); - // lower 1 of 5th, all 5 of 6th, high 2 of 7th - t[3] = (s[4] << 7) | (s[5] << 2) | (s[6] >> 3); - // lower 3 of 7th, all of 8th - t[4] = ((s[6] & 0x07) << 5) | s[7]; - - try { - for (int j = 0; j < blocklen; j++) - ds.writeByte((byte) (t[j] & 0xFF)); - } - catch (IOException e) { - } - } - - return bs.toByteArray(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/utils/base64.java b/src/main/java/core/org/xbill/DNS/utils/base64.java deleted file mode 100644 index 54567cf0..00000000 --- a/src/main/java/core/org/xbill/DNS/utils/base64.java +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS.utils; - -import java.io.*; - -/** - * Routines for converting between Strings of base64-encoded data and arrays of - * binary data. - * - * @author Brian Wellington - */ - -public class base64 { - -private static final String Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - -private -base64() {} - -/** - * Convert binary data to a base64-encoded String - * @param b An array containing binary data - * @return A String containing the encoded data - */ -public static String -toString(byte [] b) { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - for (int i = 0; i < (b.length + 2) / 3; i++) { - short [] s = new short[3]; - short [] t = new short[4]; - for (int j = 0; j < 3; j++) { - if ((i * 3 + j) < b.length) - s[j] = (short) (b[i*3+j] & 0xFF); - else - s[j] = -1; - } - - t[0] = (short) (s[0] >> 2); - if (s[1] == -1) - t[1] = (short) (((s[0] & 0x3) << 4)); - else - t[1] = (short) (((s[0] & 0x3) << 4) + (s[1] >> 4)); - if (s[1] == -1) - t[2] = t[3] = 64; - else if (s[2] == -1) { - t[2] = (short) (((s[1] & 0xF) << 2)); - t[3] = 64; - } - else { - t[2] = (short) (((s[1] & 0xF) << 2) + (s[2] >> 6)); - t[3] = (short) (s[2] & 0x3F); - } - for (int j = 0; j < 4; j++) - os.write(Base64.charAt(t[j])); - } - return new String(os.toByteArray()); -} - -/** - * Formats data into a nicely formatted base64 encoded String - * @param b An array containing binary data - * @param lineLength The number of characters per line - * @param prefix A string prefixing the characters on each line - * @param addClose Whether to add a close parenthesis or not - * @return A String representing the formatted output - */ -public static String -formatString(byte [] b, int lineLength, String prefix, boolean addClose) { - String s = toString(b); - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < s.length(); i += lineLength) { - sb.append (prefix); - if (i + lineLength >= s.length()) { - sb.append(s.substring(i)); - if (addClose) - sb.append(" )"); - } - else { - sb.append(s.substring(i, i + lineLength)); - sb.append("\n"); - } - } - return sb.toString(); -} - - -/** - * Convert a base64-encoded String to binary data - * @param str A String containing the encoded data - * @return An array containing the binary data, or null if the string is invalid - */ -public static byte [] -fromString(String str) { - ByteArrayOutputStream bs = new ByteArrayOutputStream(); - byte [] raw = str.getBytes(); - for (int i = 0; i < raw.length; i++) { - if (!Character.isWhitespace((char)raw[i])) - bs.write(raw[i]); - } - byte [] in = bs.toByteArray(); - if (in.length % 4 != 0) { - return null; - } - - bs.reset(); - DataOutputStream ds = new DataOutputStream(bs); - - for (int i = 0; i < (in.length + 3) / 4; i++) { - short [] s = new short[4]; - short [] t = new short[3]; - - for (int j = 0; j < 4; j++) - s[j] = (short) Base64.indexOf(in[i*4+j]); - - t[0] = (short) ((s[0] << 2) + (s[1] >> 4)); - if (s[2] == 64) { - t[1] = t[2] = (short) (-1); - if ((s[1] & 0xF) != 0) - return null; - } - else if (s[3] == 64) { - t[1] = (short) (((s[1] << 4) + (s[2] >> 2)) & 0xFF); - t[2] = (short) (-1); - if ((s[2] & 0x3) != 0) - return null; - } - else { - t[1] = (short) (((s[1] << 4) + (s[2] >> 2)) & 0xFF); - t[2] = (short) (((s[2] << 6) + s[3]) & 0xFF); - } - - try { - for (int j = 0; j < 3; j++) - if (t[j] >= 0) - ds.writeByte(t[j]); - } - catch (IOException e) { - } - } - return bs.toByteArray(); -} - -} diff --git a/src/main/java/core/org/xbill/DNS/utils/hexdump.java b/src/main/java/core/org/xbill/DNS/utils/hexdump.java deleted file mode 100644 index 1a79a402..00000000 --- a/src/main/java/core/org/xbill/DNS/utils/hexdump.java +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package org.xbill.DNS.utils; - -/** - * A routine to produce a nice looking hex dump - * - * @author Brian Wellington - */ - -public class hexdump { - -private static final char [] hex = "0123456789ABCDEF".toCharArray(); - -/** - * Dumps a byte array into hex format. - * @param description If not null, a description of the data. - * @param b The data to be printed. - * @param offset The start of the data in the array. - * @param length The length of the data in the array. - */ -public static String -dump(String description, byte [] b, int offset, int length) { - StringBuffer sb = new StringBuffer(); - - sb.append(length + "b"); - if (description != null) - sb.append(" (" + description + ")"); - sb.append(':'); - - int prefixlen = sb.toString().length(); - prefixlen = (prefixlen + 8) & ~ 7; - sb.append('\t'); - - int perline = (80 - prefixlen) / 3; - for (int i = 0; i < length; i++) { - if (i != 0 && i % perline == 0) { - sb.append('\n'); - for (int j = 0; j < prefixlen / 8 ; j++) - sb.append('\t'); - } - int value = (int)(b[i + offset]) & 0xFF; - sb.append(hex[(value >> 4)]); - sb.append(hex[(value & 0xF)]); - sb.append(' '); - } - sb.append('\n'); - return sb.toString(); -} - -public static String -dump(String s, byte [] b) { - return dump(s, b, 0, b.length); -} - -} diff --git a/src/main/java/core/packetproxy/DNSSpoofingIPGetter.java b/src/main/java/core/packetproxy/DNSSpoofingIPGetter.java new file mode 100644 index 00000000..2e69a30f --- /dev/null +++ b/src/main/java/core/packetproxy/DNSSpoofingIPGetter.java @@ -0,0 +1,43 @@ +/* + * Copyright 2026 DeNA Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package packetproxy; + +import packetproxy.gui.GUIOptionPrivateDNS; + +public class DNSSpoofingIPGetter { + + private final GUIOptionPrivateDNS gui; + + public DNSSpoofingIPGetter(GUIOptionPrivateDNS gui) { + this.gui = gui; + } + + public boolean isAuto() { + return gui.isAutoSpoofing(); + } + + public String get() { + return gui.getSpoofingIP(); + } + + public String get6() { + return gui.getSpoofingIP6(); + } + + public String getInt() { + return gui.getBindInterface(); + } +} diff --git a/src/main/java/core/packetproxy/PrivateDNS.java b/src/main/java/core/packetproxy/PrivateDNS.java index c849b2fc..8ce0d70c 100644 --- a/src/main/java/core/packetproxy/PrivateDNS.java +++ b/src/main/java/core/packetproxy/PrivateDNS.java @@ -393,7 +393,7 @@ public void run() { } else if (queryRecType == Type.HTTPS) { log("[DNS Query] '%s' [HTTPS]", queryHostName); - jnamed jn; + PrivateDnsResponseBuilder jn; if (isTargetHost(queryHostName)) { Name label = Name.fromString(queryHostName + "."); @@ -402,12 +402,12 @@ public void run() { alpn.fromString("h1,h2,h3"); List params = List.of(alpn); HTTPSRecord record = new HTTPSRecord(label, DClass.IN, 300, 1, svcDomain, params); - jn = new jnamed(record); + jn = new PrivateDnsResponseBuilder(record); log("Force to access '%s' with HTTP3", queryHostName); } else { Record[] records = PrivateDNSClient.getHTTPSRecord(queryHostName); - jn = new jnamed(records); + jn = new PrivateDnsResponseBuilder(records); } res = jn.generateReply(smsg, smsgBA, smsgBA.length, null); sendPacket = new DatagramPacket(res, res.length, cAddr, cPort); @@ -442,25 +442,25 @@ public void run() { log("Replaced to %s", ip); } } - jnamed jn = new jnamed(ip); + PrivateDnsResponseBuilder jn = new PrivateDnsResponseBuilder(ip); res = jn.generateReply(smsg, smsgBA, smsgBA.length, null); } catch (UnknownHostException e) { err("[DNS Query] Unknown Host: '%s' [%s]", queryHostName, queryRecTypeName); - jnamed jn = new jnamed(); + PrivateDnsResponseBuilder jn = new PrivateDnsResponseBuilder(); res = jn.generateReply(smsg, smsgBA, smsgBA.length, null); } catch (UnsupportedOperationException e) { // Not implemented yet - jnamed jn = new jnamed(); + PrivateDnsResponseBuilder jn = new PrivateDnsResponseBuilder(); res = jn.generateReply(smsg, smsgBA, smsgBA.length, null); } catch (Exception e) { err("[DNS Query] Unknown Error: '%s' [%s]", queryHostName, queryRecTypeName); - jnamed jn = new jnamed(); + PrivateDnsResponseBuilder jn = new PrivateDnsResponseBuilder(); res = jn.generateReply(smsg, smsgBA, smsgBA.length, null); } sendPacket = new DatagramPacket(res, res.length, cAddr, cPort); diff --git a/src/main/java/core/packetproxy/PrivateDNSClient.java b/src/main/java/core/packetproxy/PrivateDNSClient.java index 35b5ad28..f7519a25 100644 --- a/src/main/java/core/packetproxy/PrivateDNSClient.java +++ b/src/main/java/core/packetproxy/PrivateDNSClient.java @@ -28,7 +28,7 @@ import org.xbill.DNS.Address; import org.xbill.DNS.Lookup; import org.xbill.DNS.Record; -import org.xbill.DNS.SystemResolverConfig; +import org.xbill.DNS.ResolverConfig; import org.xbill.DNS.TextParseException; import org.xbill.DNS.Type; import packetproxy.model.Resolution; @@ -38,7 +38,6 @@ public class PrivateDNSClient { private static Resolutions resolutions; - private static PacketProxyUtility util; private static boolean isLoopbackAddress(String addr) { return addr.equals("127.0.0.1") || addr.equals("0:0:0:0:0:0:0:1") || addr.equals("::1"); @@ -53,6 +52,15 @@ private static boolean dnsLooping(String serverName) throws Exception { return dnsLoopDetectedInDnsServer() || dnsLoopDetectedInEtcHosts(serverName); } + static String getCurrentSystemDnsServerAddress() { + ResolverConfig.refresh(); + var resolverConfig = ResolverConfig.getCurrentConfig(); + if (resolverConfig == null || resolverConfig.server() == null) { + return null; + } + return resolverConfig.server().getAddress().getHostAddress(); + } + // システムのDNS設定が、PacketProxyのDNSサーバが設定されているときtrueになる private static boolean dnsLoopDetectedInDnsServer() throws Exception { if (!PrivateDNS.getInstance().isRunning()) { @@ -61,8 +69,10 @@ private static boolean dnsLoopDetectedInDnsServer() throws Exception { } // current system dns server setting - SystemResolverConfig systemResolver = new SystemResolverConfig(); - String dnsServer = systemResolver.server(); + var dnsServer = getCurrentSystemDnsServerAddress(); + if (dnsServer == null) { + return false; + } if (isLoopbackAddress(dnsServer)) { @@ -104,8 +114,7 @@ public static boolean dnsLoopingFromHostsLines(List fileLines, String se } public static InetAddress getByName(String serverName) throws Exception { - resolutions = resolutions.getInstance(); - util = PacketProxyUtility.getInstance(); + resolutions = Resolutions.getInstance(); List resolution_list = resolutions.queryEnabled(); for (Resolution resolution : resolution_list) { diff --git a/src/main/java/core/packetproxy/PrivateDnsResponseBuilder.java b/src/main/java/core/packetproxy/PrivateDnsResponseBuilder.java new file mode 100644 index 00000000..09518b54 --- /dev/null +++ b/src/main/java/core/packetproxy/PrivateDnsResponseBuilder.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 1998-2011, Brian Wellington. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package packetproxy; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import org.xbill.DNS.AAAARecord; +import org.xbill.DNS.ARecord; +import org.xbill.DNS.ExtendedFlags; +import org.xbill.DNS.Flags; +import org.xbill.DNS.Header; +import org.xbill.DNS.Message; +import org.xbill.DNS.OPTRecord; +import org.xbill.DNS.Opcode; +import org.xbill.DNS.Rcode; +import org.xbill.DNS.Record; +import org.xbill.DNS.Section; +import org.xbill.DNS.Type; + +public class PrivateDnsResponseBuilder { + + private final String spoofIP; + private final Record answer; + private final Record[] answers; + + public PrivateDnsResponseBuilder() { + this(null, null, null); + } + + public PrivateDnsResponseBuilder(String ip) { + this(ip, null, null); + } + + public PrivateDnsResponseBuilder(Record answer) { + this(null, answer, null); + } + + public PrivateDnsResponseBuilder(Record[] answers) { + this(null, null, answers); + } + + private PrivateDnsResponseBuilder(String spoofIP, Record answer, Record[] answers) { + this.spoofIP = spoofIP; + this.answer = answer; + this.answers = answers; + } + + public byte[] generateReply(Message query, byte[] in, int length, Socket s) throws IOException { + var header = query.getHeader(); + if (header.getFlag(Flags.QR)) { + return null; + } + if (header.getRcode() != Rcode.NOERROR) { + return errorMessage(query, Rcode.FORMERR); + } + if (header.getOpcode() != Opcode.QUERY) { + return errorMessage(query, Rcode.NOTIMP); + } + + var queryRecord = query.getQuestion(); + var queryOpt = query.getOPT(); + var response = new Message(header.getID()); + response.getHeader().setFlag(Flags.QR); + if (header.getFlag(Flags.RD)) { + response.getHeader().setFlag(Flags.RD); + } + response.addRecord(queryRecord, Section.QUESTION); + + if (answer != null) { + response.addRecord(answer, Section.ANSWER); + } + if (answers != null) { + for (var record : answers) { + if (record != null) { + response.addRecord(record, Section.ANSWER); + } + } + } + if (spoofIP != null) { + response.addRecord(createSpoofedRecord(queryRecord), Section.ANSWER); + } + + var maxLength = getMaxLength(queryOpt, s); + addOptRecord(response, queryOpt); + return response.toWire(maxLength); + } + + private Record createSpoofedRecord(Record queryRecord) throws IOException { + var name = queryRecord.getName(); + var dclass = queryRecord.getDClass(); + var address = InetAddress.getByName(spoofIP); + if (queryRecord.getType() == Type.A) { + return new ARecord(name, dclass, 0, address); + } + return new AAAARecord(name, dclass, 0, address); + } + + private int getMaxLength(OPTRecord queryOpt, Socket s) { + if (s != null) { + return 65535; + } + if (queryOpt != null) { + return Math.max(queryOpt.getPayloadSize(), 512); + } + return 512; + } + + private void addOptRecord(Message response, OPTRecord queryOpt) { + if (queryOpt == null) { + return; + } + var optFlags = (queryOpt.getFlags() & ExtendedFlags.DO) != 0 ? ExtendedFlags.DO : 0; + response.addRecord(new OPTRecord((short) 4096, Rcode.NOERROR, (byte) 0, optFlags), Section.ADDITIONAL); + } + + private byte[] errorMessage(Message query, int rcode) { + return buildErrorMessage(query.getHeader(), rcode, query.getQuestion()); + } + + private byte[] buildErrorMessage(Header header, int rcode, Record question) { + var response = new Message(); + response.setHeader(header); + for (var i = Section.QUESTION; i <= Section.ADDITIONAL; i++) { + response.removeAllRecords(i); + } + if (rcode == Rcode.SERVFAIL && question != null) { + response.addRecord(question, Section.QUESTION); + } + header.setRcode(rcode); + return response.toWire(); + } +} diff --git a/src/main/java/core/packetproxy/gui/GUIOptionPrivateDNS.java b/src/main/java/core/packetproxy/gui/GUIOptionPrivateDNS.java index 6ffd589e..7bd21618 100644 --- a/src/main/java/core/packetproxy/gui/GUIOptionPrivateDNS.java +++ b/src/main/java/core/packetproxy/gui/GUIOptionPrivateDNS.java @@ -54,7 +54,7 @@ import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.DocumentFilter; -import org.xbill.DNS.DNSSpoofingIPGetter; +import packetproxy.DNSSpoofingIPGetter; import packetproxy.PrivateDNS; import packetproxy.common.FontManager; import packetproxy.common.I18nString; diff --git a/src/test/java/org/xbill/DNS/HTTPSRecordTest.java b/src/test/java/org/xbill/DNS/HTTPSRecordTest.java index 03b98a34..bebce7be 100644 --- a/src/test/java/org/xbill/DNS/HTTPSRecordTest.java +++ b/src/test/java/org/xbill/DNS/HTTPSRecordTest.java @@ -10,7 +10,6 @@ import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; @@ -18,38 +17,38 @@ public class HTTPSRecordTest { @Test - void createParams() throws UnknownHostException { + void createParams() throws Exception { List mandatoryList = Arrays.asList(HTTPSRecord.ALPN, HTTPSRecord.IPV4HINT); - HTTPSRecord.ParameterMandatory mandatory = new HTTPSRecord.ParameterMandatory(mandatoryList); + SVCBBase.ParameterMandatory mandatory = new SVCBBase.ParameterMandatory(mandatoryList); assertEquals(HTTPSRecord.MANDATORY, mandatory.getKey()); assertEquals(mandatoryList, mandatory.getValues()); List alpnList = Arrays.asList("h2", "h3"); - HTTPSRecord.ParameterAlpn alpn = new HTTPSRecord.ParameterAlpn(alpnList); + SVCBBase.ParameterAlpn alpn = new SVCBBase.ParameterAlpn(alpnList); assertEquals(HTTPSRecord.ALPN, alpn.getKey()); assertEquals(alpnList, alpn.getValues()); - HTTPSRecord.ParameterPort port = new HTTPSRecord.ParameterPort(8443); + SVCBBase.ParameterPort port = new SVCBBase.ParameterPort(8443); assertEquals(HTTPSRecord.PORT, port.getKey()); assertEquals(8443, port.getPort()); List ipv4List = Arrays.asList((Inet4Address) InetAddress.getByName("1.2.3.4")); - HTTPSRecord.ParameterIpv4Hint ipv4hint = new HTTPSRecord.ParameterIpv4Hint(ipv4List); + SVCBBase.ParameterIpv4Hint ipv4hint = new SVCBBase.ParameterIpv4Hint(ipv4List); assertEquals(HTTPSRecord.IPV4HINT, ipv4hint.getKey()); assertEquals(ipv4List, ipv4hint.getAddresses()); byte[] data = {'a', 'b', 'c'}; - HTTPSRecord.ParameterEchConfig echconfig = new HTTPSRecord.ParameterEchConfig(data); + SVCBBase.ParameterEchConfig echconfig = new SVCBBase.ParameterEchConfig(data); assertEquals(HTTPSRecord.ECHCONFIG, echconfig.getKey()); assertEquals(data, echconfig.getData()); List ipv6List = Arrays.asList((Inet6Address) InetAddress.getByName("2001::1")); - HTTPSRecord.ParameterIpv6Hint ipv6hint = new HTTPSRecord.ParameterIpv6Hint(ipv6List); + SVCBBase.ParameterIpv6Hint ipv6hint = new SVCBBase.ParameterIpv6Hint(ipv6List); assertEquals(HTTPSRecord.IPV6HINT, ipv6hint.getKey()); assertEquals(ipv6List, ipv6hint.getAddresses()); byte[] value = {0, 1, 2, 3}; - HTTPSRecord.ParameterUnknown unknown = new HTTPSRecord.ParameterUnknown(33, value); + SVCBBase.ParameterUnknown unknown = new SVCBBase.ParameterUnknown(33, value); assertEquals(33, unknown.getKey()); assertEquals(value, unknown.getValue()); } @@ -59,13 +58,13 @@ void createRecord() throws IOException { Name label = Name.fromString("test.com."); int svcPriority = 5; Name svcDomain = Name.fromString("svc.test.com."); - HTTPSRecord.ParameterMandatory mandatory = new HTTPSRecord.ParameterMandatory(); + SVCBBase.ParameterMandatory mandatory = new SVCBBase.ParameterMandatory(); mandatory.fromString("alpn"); - HTTPSRecord.ParameterAlpn alpn = new HTTPSRecord.ParameterAlpn(); + SVCBBase.ParameterAlpn alpn = new SVCBBase.ParameterAlpn(); alpn.fromString("h1,h2"); - HTTPSRecord.ParameterIpv4Hint ipv4 = new HTTPSRecord.ParameterIpv4Hint(); + SVCBBase.ParameterIpv4Hint ipv4 = new SVCBBase.ParameterIpv4Hint(); ipv4.fromString("1.2.3.4,5.6.7.8"); - List params = Arrays.asList(mandatory, ipv4, alpn); + List params = Arrays.asList(mandatory, ipv4, alpn); HTTPSRecord record = new HTTPSRecord(label, DClass.IN, 300, svcPriority, svcDomain, params); assertEquals(Type.HTTPS, record.getType()); @@ -105,7 +104,7 @@ void serviceModePort() throws IOException { @Test void serviceModeEchConfigMulti() throws IOException { String str = "1 h3pool. alpn=h2,h3 echconfig=1234"; - assertEquals(str, SVCBRecordTest.stringToWireToString(str)); + assertEquals("1 h3pool. alpn=h2,h3 ech=1234", SVCBRecordTest.stringToWireToString(str)); } @Test diff --git a/src/test/java/org/xbill/DNS/SVCBRecordTest.java b/src/test/java/org/xbill/DNS/SVCBRecordTest.java index d364e159..6e1e916e 100644 --- a/src/test/java/org/xbill/DNS/SVCBRecordTest.java +++ b/src/test/java/org/xbill/DNS/SVCBRecordTest.java @@ -10,7 +10,6 @@ import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; @@ -18,38 +17,38 @@ public class SVCBRecordTest { @Test - void createParams() throws UnknownHostException { + void createParams() throws Exception { List mandatoryList = Arrays.asList(SVCBRecord.ALPN, SVCBRecord.IPV4HINT); - SVCBRecord.ParameterMandatory mandatory = new SVCBBase.ParameterMandatory(mandatoryList); + SVCBBase.ParameterMandatory mandatory = new SVCBBase.ParameterMandatory(mandatoryList); assertEquals(SVCBRecord.MANDATORY, mandatory.getKey()); assertEquals(mandatoryList, mandatory.getValues()); List alpnList = Arrays.asList("h2", "h3"); - SVCBRecord.ParameterAlpn alpn = new SVCBRecord.ParameterAlpn(alpnList); + SVCBBase.ParameterAlpn alpn = new SVCBBase.ParameterAlpn(alpnList); assertEquals(SVCBRecord.ALPN, alpn.getKey()); assertEquals(alpnList, alpn.getValues()); - SVCBRecord.ParameterPort port = new SVCBBase.ParameterPort(8443); + SVCBBase.ParameterPort port = new SVCBBase.ParameterPort(8443); assertEquals(SVCBRecord.PORT, port.getKey()); assertEquals(8443, port.getPort()); List ipv4List = Arrays.asList((Inet4Address) InetAddress.getByName("1.2.3.4")); - SVCBRecord.ParameterIpv4Hint ipv4hint = new SVCBRecord.ParameterIpv4Hint(ipv4List); + SVCBBase.ParameterIpv4Hint ipv4hint = new SVCBBase.ParameterIpv4Hint(ipv4List); assertEquals(SVCBRecord.IPV4HINT, ipv4hint.getKey()); assertEquals(ipv4List, ipv4hint.getAddresses()); byte[] data = {'a', 'b', 'c'}; - SVCBRecord.ParameterEchConfig echconfig = new SVCBRecord.ParameterEchConfig(data); + SVCBBase.ParameterEchConfig echconfig = new SVCBBase.ParameterEchConfig(data); assertEquals(SVCBRecord.ECHCONFIG, echconfig.getKey()); assertEquals(data, echconfig.getData()); List ipv6List = Arrays.asList((Inet6Address) InetAddress.getByName("2001::1")); - SVCBRecord.ParameterIpv6Hint ipv6hint = new SVCBRecord.ParameterIpv6Hint(ipv6List); + SVCBBase.ParameterIpv6Hint ipv6hint = new SVCBBase.ParameterIpv6Hint(ipv6List); assertEquals(SVCBRecord.IPV6HINT, ipv6hint.getKey()); assertEquals(ipv6List, ipv6hint.getAddresses()); byte[] value = {0, 1, 2, 3}; - SVCBRecord.ParameterUnknown unknown = new SVCBRecord.ParameterUnknown(33, value); + SVCBBase.ParameterUnknown unknown = new SVCBBase.ParameterUnknown(33, value); assertEquals(33, unknown.getKey()); assertEquals(value, unknown.getValue()); } @@ -59,13 +58,13 @@ void createRecord() throws IOException { Name label = Name.fromString("test.com."); int svcPriority = 5; Name svcDomain = Name.fromString("svc.test.com."); - SVCBRecord.ParameterMandatory mandatory = new SVCBRecord.ParameterMandatory(); + SVCBBase.ParameterMandatory mandatory = new SVCBBase.ParameterMandatory(); mandatory.fromString("alpn"); - SVCBRecord.ParameterAlpn alpn = new SVCBRecord.ParameterAlpn(); + SVCBBase.ParameterAlpn alpn = new SVCBBase.ParameterAlpn(); alpn.fromString("h1,h2"); - SVCBRecord.ParameterIpv4Hint ipv4 = new SVCBRecord.ParameterIpv4Hint(); + SVCBBase.ParameterIpv4Hint ipv4 = new SVCBBase.ParameterIpv4Hint(); ipv4.fromString("1.2.3.4,5.6.7.8"); - List params = Arrays.asList(mandatory, ipv4, alpn); + List params = Arrays.asList(mandatory, ipv4, alpn); SVCBRecord record = new SVCBRecord(label, DClass.IN, 300, svcPriority, svcDomain, params); assertEquals(Type.SVCB, record.getType()); @@ -88,11 +87,11 @@ void createRecord() throws IOException { void createRecordDuplicateParam() throws IOException { Name label = Name.fromString("test.com."); Name svcDomain = Name.fromString("svc.test.com."); - SVCBRecord.ParameterAlpn alpn = new SVCBRecord.ParameterAlpn(); + SVCBBase.ParameterAlpn alpn = new SVCBBase.ParameterAlpn(); alpn.fromString("h1,h2"); - SVCBRecord.ParameterIpv4Hint ipv4 = new SVCBRecord.ParameterIpv4Hint(); + SVCBBase.ParameterIpv4Hint ipv4 = new SVCBBase.ParameterIpv4Hint(); ipv4.fromString("1.2.3.4,5.6.7.8"); - List params = Arrays.asList(alpn, ipv4, alpn); + List params = Arrays.asList(alpn, ipv4, alpn); assertThrows(IllegalArgumentException.class, () -> { new SVCBRecord(label, DClass.IN, 300, 5, svcDomain, params); }); @@ -176,25 +175,25 @@ void serviceModeEscapedDomain() throws IOException { @Test void serviceModeEchConfig() throws IOException { String str = "1 h3pool. echconfig=1234"; - assertEquals(str, stringToWireToString(str)); + assertEquals("1 h3pool. ech=1234", stringToWireToString(str)); } @Test void serviceModeEchConfigMulti() throws IOException { String str = "1 h3pool. alpn=h2,h3 echconfig=1234"; - assertEquals(str, stringToWireToString(str)); + assertEquals("1 h3pool. alpn=h2,h3 ech=1234", stringToWireToString(str)); } @Test void serviceModeEchConfigOutOfOrder() throws IOException { String str = "1 h3pool. echconfig=1234 alpn=h2,h3"; - assertEquals("1 h3pool. alpn=h2,h3 echconfig=1234", stringToWireToString(str)); + assertEquals("1 h3pool. alpn=h2,h3 ech=1234", stringToWireToString(str)); } @Test void serviceModeEchConfigQuoted() throws IOException { String str = "1 h3pool. alpn=h2,h3 echconfig=\"1234\""; - assertEquals("1 h3pool. alpn=h2,h3 echconfig=1234", stringToWireToString(str)); + assertEquals("1 h3pool. alpn=h2,h3 ech=1234", stringToWireToString(str)); } @Test @@ -292,11 +291,9 @@ void extraQuotesInParamValues() { } @Test - void serviceModeWithoutParameters() { + void serviceModeWithoutParameters() throws IOException { String str = "1 aliasmode.example.com."; - assertThrows(TextParseException.class, () -> { - stringToWire(str); - }); + assertEquals(str, stringToWireToString(str)); } @Test @@ -436,11 +433,9 @@ void emptyString() { } @Test - void noParamValues() { + void noParamValues() throws IOException { String str = "1 ."; - assertThrows(TextParseException.class, () -> { - stringToWire(str); - }); + assertEquals(str, stringToWireToString(str)); } @Test diff --git a/src/test/java/packetproxy/PrivateDNSClientTest.java b/src/test/java/packetproxy/PrivateDNSClientTest.java index d067423d..2551b585 100644 --- a/src/test/java/packetproxy/PrivateDNSClientTest.java +++ b/src/test/java/packetproxy/PrivateDNSClientTest.java @@ -18,8 +18,15 @@ import static org.junit.jupiter.api.Assertions.*; +import java.net.InetAddress; +import java.net.InetSocketAddress; import java.util.ArrayList; +import java.util.List; import org.junit.jupiter.api.Test; +import org.xbill.DNS.Name; +import org.xbill.DNS.ResolverConfig; +import org.xbill.DNS.config.InitializationException; +import org.xbill.DNS.config.ResolverConfigProvider; class PrivateDNSClientTest { @@ -78,4 +85,48 @@ class PrivateDNSClientTest { lines.add(" # 3.3.3.3 aaa ccc.example.com"); assertFalse(PrivateDNSClient.dnsLoopingFromHostsLines(lines, "aaa.example.com")); } + + @Test + public void システムDNS設定を再読込する() throws Exception { + var originalProviders = ResolverConfig.getConfigProviders(); + var provider = new TestResolverConfigProvider("127.0.0.1"); + try { + ResolverConfig.setConfigProviders(List.of(provider)); + ResolverConfig.refresh(); + + provider.setServer("8.8.8.8"); + + assertEquals("8.8.8.8", PrivateDNSClient.getCurrentSystemDnsServerAddress()); + } finally { + ResolverConfig.setConfigProviders(originalProviders); + ResolverConfig.refresh(); + } + } + + private static class TestResolverConfigProvider implements ResolverConfigProvider { + + private List servers; + + private TestResolverConfigProvider(String server) throws Exception { + setServer(server); + } + + private void setServer(String server) throws Exception { + servers = List.of(new InetSocketAddress(InetAddress.getByName(server), 53)); + } + + @Override + public void initialize() throws InitializationException { + } + + @Override + public List servers() { + return servers; + } + + @Override + public List searchPaths() { + return List.of(); + } + } }