Commit 2c0bd49e authored by Grigory Fedorov's avatar Grigory Fedorov

Merge branch 'develop' into feature/chat_scroll

parents c03b787a d3ee174d
......@@ -28,5 +28,6 @@ dependencies {
compile 'com.github.ksoichiro:android-observablescrollview:1.5.0'
compile 'de.hdodenhof:circleimageview:1.2.2'
compile 'com.melnykov:floatingactionbutton:1.2.0'
compile 'dnsjava:dnsjava:2.1.7'
compile project('otr4j')
}
Subproject commit 295de3b53f054625ecdcf0d5a5db4fc846144013
Subproject commit 0ced840950b4db1a403ea085b642a7028b1ef03d
......@@ -102,11 +102,7 @@ public class DNSManager {
}
for (Resolver check : resolver.getResolvers())
if (check instanceof SimpleResolver) {
LogManager.i(check, "Current timeout is "
+ ((SimpleResolver) check).getTimeout());
((SimpleResolver) check).setTimeout(30);
LogManager.i(check, "new value is "
+ ((SimpleResolver) check).getTimeout());
} else {
LogManager.i(this, "Not simple resolver!!!?" + check);
}
......
......@@ -365,8 +365,7 @@ public class OTRManager implements OtrEngineHost, OtrEngineListener,
PublicKey remotePublicKey = session.getRemotePublicKey();
String value;
try {
value = new OtrCryptoEngine()
.getFingerprint(remotePublicKey);
value = OtrCryptoEngine.getFingerprint(remotePublicKey);
} catch (OtrCryptoException e) {
LogManager.exception(this, e);
value = null;
......@@ -542,7 +541,7 @@ public class OTRManager implements OtrEngineHost, OtrEngineListener,
public String getLocalFingerprint(String account) {
try {
return new OtrCryptoEngine().getFingerprint(getLocalKeyPair(
return OtrCryptoEngine.getFingerprint(getLocalKeyPair(
account).getPublic());
} catch (OtrCryptoException e) {
LogManager.exception(this, e);
......
// 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);
}
}
// 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 InetAddress 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;
}
void
rrFromWire(DNSInput in) throws IOException {
address = InetAddress.getByAddress(in.readByteArray(16));
}
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
address = st.getAddress(Address.IPv6);
}
/**
* Converts rdata to a String
*/
String
rrToString() {
return address.getHostAddress();
}
/**
* Returns the address
*/
public InetAddress
getAddress() {
return address;
}
void
rrToWire(DNSOutput out, Compression c, boolean canonical) {
out.writeByteArray(address.getAddress());
}
}
// 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();
}
}
// 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);
}
}
}
// 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 {
InetAddress address = st.getAddress(Address.IPv4);
addr = fromArray(address.getAddress());
}
/**
* Converts rdata to a String
*/
String
rrToString() {
return (Address.toDottedQuad(toArray(addr)));
}
/**
* Returns the Internet address
*/
public InetAddress
getAddress() {
try {
return InetAddress.getByAddress(toArray(addr));
} catch (UnknownHostException e) {
return null;
}
}
void
rrToWire(DNSOutput out, Compression c, boolean canonical) {
out.writeU32(((long) addr) & 0xFFFFFFFFL);
}
}
This diff is collapsed.
// 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.
*
* @author Brian Wellington
* @see KEYRecord
*/
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);
}
}
// 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();
}
}
This diff is collapsed.
// 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;
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, byte[] data) {
if (Options.check("verbosemsg"))
System.err.println(hexdump.dump(prefix, data));
}
void
cleanup() throws IOException {
key.selector().close();
key.channel().close();
}
}
// 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").
* <p/>
* 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.
* <p/>
* The option is transmitted as part of an OPTRecord in the additional section
* of a DNS message, as defined by RFC 2671 (EDNS0).
* <p/>
* An option code has not been assigned by IANA; the value 20730 (used here) is
* also used by several other implementations.
* <p/>
* 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)
*
* @author Brian Wellington
* @author Ming Zhou &lt;mizhou@bnivideo.com&gt;, Beaumaris Networks
* @see OPTRecord
*/
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.
* XXX something about Java's 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();
}
}
// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
package org.xbill.DNS;
/**
* DNS Name Compression object.
*
* @author Brian Wellington
* @see Message
* @see Name
*/
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;
}
}
// 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.
*
* @author Brian Wellington
* @see Cache
* @see Section
*/
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;
}
// 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);
}
}
// 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;
}
}
// 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.
*
* @author David Blacka
* @author Brian Wellington
* @see DNSSEC
* @see DSRecord
*/
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);
}
}
// 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();
}
}
// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org)
package org.xbill.DNS;
/**
* An class for parsing DNS messages.
*
* @author Brian Wellington
*/
public class DNSInput {
private byte[] array;
private int pos;
private int end;
private int saved_pos;
private int saved_end;
/**
* Creates a new DNSInput
*
* @param input The byte array to read from
*/
public DNSInput(byte[] input) {
array = input;
pos = 0;
end = array.length;
saved_pos = -1;
saved_end = -1;
}
/**
* Returns the current position.
*/
public int
current() {
return pos;
}
/**
* Returns the number of bytes that can be read from this stream before
* reaching the end.
*/
public int
remaining() {
return end - pos;
}
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 > array.length - pos) {
throw new IllegalArgumentException("cannot set active " +
"region past end of input");
}
end = pos + len;
}
/**
* Clears the active region of the string. Further operations are not
* restricted to part of the input.
*/
public void
clearActive() {
end = array.length;
}
/**
* Returns the position of the end of the current active region.
*/
public int
saveActive() {
return end;
}
/**
* 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 > array.length) {
throw new IllegalArgumentException("cannot set active " +
"region past end of input");
}
end = pos;
}
/**
* 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 >= array.length) {
throw new IllegalArgumentException("cannot jump past " +
"end of input");
}
pos = index;
end = array.length;
}
/**
* 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 = pos;
saved_end = end;
}
/**
* 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;
end = 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 (array[pos++] & 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);
int b1 = array[pos++] & 0xFF;
int b2 = array[pos++] & 0xFF;
return ((b1 << 8) + b2);
}
/**
* 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);
int b1 = array[pos++] & 0xFF;
int b2 = array[pos++] & 0xFF;
int b3 = array[pos++] & 0xFF;
int b4 = array[pos++] & 0xFF;
return (((long) b1 << 24) + (b2 << 16) + (b3 << 8) + b4);
}
/**
* 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);
System.arraycopy(array, pos, b, off, len);
pos += 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];
System.arraycopy(array, pos, out, 0, len);
pos += 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];
System.arraycopy(array, pos, out, 0, len);
pos += 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 {
require(1);
int len = array[pos++] & 0xFF;
return readByteArray(len);
}
}
// 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
*
* @author Brian Wellington
* @see DNSSEC
*/
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();
}
}
// 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;
}
}
This diff is collapsed.
// 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.
*
* @author David Blacka
* @author Brian Wellington
* @see DNSSEC
*/
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;
}
public static final int SHA1_DIGEST_ID = Digest.SHA1;
public static final int SHA256_DIGEST_ID = Digest.SHA256;
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 footprint The original KEY record's footprint (keyid).
* @param digestid The digest id code.
* @param key The key to digest
*/
public DSRecord(Name name, int dclass, long ttl, int footprint, int digestid,
DNSKEYRecord key) {
this(name, dclass, ttl, footprint, key.getAlgorithm(), digestid,
DNSSEC.generateDS(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);
}
}
// 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 &lt;mizhou@bnivideo.com&gt;, 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-00
*/
public final static int CLIENT_SUBNET = 20730;
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();
}
// 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) {
}
}
// 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);
}
}
This diff is collapsed.
// 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;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// 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);
}
}
// 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);
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment