181
// in org/xbill/DNS/SSHFPRecord.java
void
rrFromWire(DNSInput in) throws IOException {
alg = in.readU8();
digestType = in.readU8();
fingerprint = in.readByteArray();
}
// in org/xbill/DNS/SSHFPRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
alg = st.getUInt8();
digestType = st.getUInt8();
fingerprint = st.getHex(true);
}
// in org/xbill/DNS/APLRecord.java
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);
}
}
// in org/xbill/DNS/APLRecord.java
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();
}
// in org/xbill/DNS/NXTRecord.java
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);
}
}
// in org/xbill/DNS/NXTRecord.java
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();
}
// in org/xbill/DNS/ISDNRecord.java
void
rrFromWire(DNSInput in) throws IOException {
address = in.readCountedString();
if (in.remaining() > 0)
subAddress = in.readCountedString();
}
// in org/xbill/DNS/ISDNRecord.java
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());
}
}
// in org/xbill/DNS/TSIGRecord.java
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;
}
// in org/xbill/DNS/TSIGRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
throw st.exception("no text format defined for TSIG");
}
// in org/xbill/DNS/ARecord.java
void
rrFromWire(DNSInput in) throws IOException {
addr = fromArray(in.readByteArray(4));
}
// in org/xbill/DNS/ARecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
InetAddress address = st.getAddress(Address.IPv4);
addr = fromArray(address.getAddress());
}
// in org/xbill/DNS/GenericEDNSOption.java
void
optionFromWire(DNSInput in) throws IOException {
data = in.readByteArray();
}
// in org/xbill/DNS/ExtendedResolver.java
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");
}
// in org/xbill/DNS/ExtendedResolver.java
public Message
send(Message query) throws IOException {
Resolution res = new Resolution(this, query);
return res.start();
}
// in org/xbill/DNS/Record.java
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;
}
// in org/xbill/DNS/Record.java
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;
}
// in org/xbill/DNS/Record.java
static Record
fromWire(DNSInput in, int section) throws IOException {
return fromWire(in, section, false);
}
// in org/xbill/DNS/Record.java
public static Record
fromWire(byte [] b, int section) throws IOException {
return fromWire(new DNSInput(b), section, false);
}
// in org/xbill/DNS/Record.java
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;
}
// in org/xbill/DNS/Record.java
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);
}
// in org/xbill/DNS/HINFORecord.java
void
rrFromWire(DNSInput in) throws IOException {
cpu = in.readCountedString();
os = in.readCountedString();
}
// in org/xbill/DNS/HINFORecord.java
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());
}
}
// in org/xbill/DNS/SimpleResolver.java
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);
}
// in org/xbill/DNS/SimpleResolver.java
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;
}
// in org/xbill/DNS/AAAARecord.java
void
rrFromWire(DNSInput in) throws IOException {
address = InetAddress.getByAddress(in.readByteArray(16));
}
// in org/xbill/DNS/AAAARecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
address = st.getAddress(Address.IPv6);
}
// in org/xbill/DNS/Master.java
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;
}
}
// in org/xbill/DNS/Master.java
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);
}
// in org/xbill/DNS/Master.java
private void
endGenerate() throws IOException {
// Read the EOL that we put back before.
st.getEOL();
generator = null;
}
// in org/xbill/DNS/Master.java
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());
}
}
// in org/xbill/DNS/Master.java
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;
}
}
// in org/xbill/DNS/Master.java
public Record
nextRecord() throws IOException {
Record rec = null;
try {
rec = _nextRecord();
}
finally {
if (rec == null) {
st.close();
}
}
return rec;
}
// in org/xbill/DNS/TXTBase.java
void
rrFromWire(DNSInput in) throws IOException {
strings = new ArrayList(2);
while (in.remaining() > 0) {
byte [] b = in.readCountedString();
strings.add(b);
}
}
// in org/xbill/DNS/TXTBase.java
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();
}
// in org/xbill/DNS/DLVRecord.java
void
rrFromWire(DNSInput in) throws IOException {
footprint = in.readU16();
alg = in.readU8();
digestid = in.readU8();
digest = in.readByteArray();
}
// in org/xbill/DNS/DLVRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
footprint = st.getUInt16();
alg = st.getUInt8();
digestid = st.getUInt8();
digest = st.getHex();
}
// in org/xbill/DNS/SingleNameBase.java
void
rrFromWire(DNSInput in) throws IOException {
singleName = new Name(in);
}
// in org/xbill/DNS/SingleNameBase.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
singleName = st.getName(origin);
}
// in org/xbill/DNS/KEYBase.java
void
rrFromWire(DNSInput in) throws IOException {
flags = in.readU16();
proto = in.readU8();
alg = in.readU8();
if (in.remaining() > 0)
key = in.readByteArray();
}
// in org/xbill/DNS/Client.java
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();
}
// in org/xbill/DNS/Client.java
void
cleanup() throws IOException {
key.selector().close();
key.channel().close();
}
// in org/xbill/DNS/NSEC3PARAMRecord.java
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;
}
// in org/xbill/DNS/NSEC3PARAMRecord.java
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");
}
}
// in org/xbill/DNS/Tokenizer.java
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;
}
// in org/xbill/DNS/Tokenizer.java
private void
ungetChar(int c) throws IOException {
if (c == -1)
return;
is.unread(c);
if (c == '\n')
line--;
}
// in org/xbill/DNS/Tokenizer.java
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++;
}
}
// in org/xbill/DNS/Tokenizer.java
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);
}
// in org/xbill/DNS/Tokenizer.java
public Token
get() throws IOException {
return get(false, false);
}
// in org/xbill/DNS/Tokenizer.java
public String
getString() throws IOException {
Token next = get();
if (!next.isString()) {
throw exception("expected a string");
}
return next.value;
}
// in org/xbill/DNS/Tokenizer.java
private String
_getIdentifier(String expected) throws IOException {
Token next = get();
if (next.type != IDENTIFIER)
throw exception("expected " + expected);
return next.value;
}
// in org/xbill/DNS/Tokenizer.java
public String
getIdentifier() throws IOException {
return _getIdentifier("an identifier");
}
// in org/xbill/DNS/Tokenizer.java
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");
}
}
// in org/xbill/DNS/Tokenizer.java
public long
getUInt32() throws IOException {
long l = getLong();
if (l < 0 || l > 0xFFFFFFFFL)
throw exception("expected an 32 bit unsigned integer");
return l;
}
// in org/xbill/DNS/Tokenizer.java
public int
getUInt16() throws IOException {
long l = getLong();
if (l < 0 || l > 0xFFFFL)
throw exception("expected an 16 bit unsigned integer");
return (int) l;
}
// in org/xbill/DNS/Tokenizer.java
public int
getUInt8() throws IOException {
long l = getLong();
if (l < 0 || l > 0xFFL)
throw exception("expected an 8 bit unsigned integer");
return (int) l;
}
// in org/xbill/DNS/Tokenizer.java
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");
}
}
// in org/xbill/DNS/Tokenizer.java
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");
}
}
// in org/xbill/DNS/Tokenizer.java
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());
}
}
// in org/xbill/DNS/Tokenizer.java
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());
}
}
// in org/xbill/DNS/Tokenizer.java
public void
getEOL() throws IOException {
Token next = get();
if (next.type != EOL && next.type != EOF) {
throw exception("expected EOL or EOF");
}
}
// in org/xbill/DNS/Tokenizer.java
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();
}
// in org/xbill/DNS/Tokenizer.java
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;
}
// in org/xbill/DNS/Tokenizer.java
public byte []
getBase64() throws IOException {
return getBase64(false);
}
// in org/xbill/DNS/Tokenizer.java
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;
}
// in org/xbill/DNS/Tokenizer.java
public byte []
getHex() throws IOException {
return getHex(false);
}
// in org/xbill/DNS/Tokenizer.java
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;
}
// in org/xbill/DNS/Tokenizer.java
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;
}
// in org/xbill/DNS/A6Record.java
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);
}
// in org/xbill/DNS/A6Record.java
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);
}
// in org/xbill/DNS/DNSSEC.java
private static BigInteger
readBigInteger(DNSInput in, int len) throws IOException {
byte [] b = in.readByteArray(len);
return new BigInteger(1, b);
}
// in org/xbill/DNS/DNSSEC.java
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));
}
// in org/xbill/DNS/DNSSEC.java
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));
}
// in org/xbill/DNS/DNSSEC.java
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();
}
// in org/xbill/DNS/DNSSEC.java
private static byte []
DSASignaturetoDNS(byte [] key, int t) throws IOException {
DNSInput in = new DNSInput(key);
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();
}
// in org/xbill/DNS/RPRecord.java
void
rrFromWire(DNSInput in) throws IOException {
mailbox = new Name(in);
textDomain = new Name(in);
}
// in org/xbill/DNS/RPRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
mailbox = st.getName(origin);
textDomain = st.getName(origin);
}
// in org/xbill/DNS/DHCIDRecord.java
void
rrFromWire(DNSInput in) throws IOException {
data = in.readByteArray();
}
// in org/xbill/DNS/DHCIDRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
data = st.getBase64();
}
// in org/xbill/DNS/NULLRecord.java
void
rrFromWire(DNSInput in) throws IOException {
data = in.readByteArray();
}
// in org/xbill/DNS/NULLRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
throw st.exception("no defined text format for NULL records");
}
// in org/xbill/DNS/DNSKEYRecord.java
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();
}
// in org/xbill/DNS/CERTRecord.java
void
rrFromWire(DNSInput in) throws IOException {
certType = in.readU16();
keyTag = in.readU16();
alg = in.readU8();
cert = in.readByteArray();
}
// in org/xbill/DNS/CERTRecord.java
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();
}
// in org/xbill/DNS/Generator.java
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();
}
// in org/xbill/DNS/Generator.java
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);
}
// in org/xbill/DNS/Generator.java
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()]);
}
// in org/xbill/DNS/TKEYRecord.java
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;
}
// in org/xbill/DNS/TKEYRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
throw st.exception("no text format defined for TKEY");
}
// in org/xbill/DNS/EmptyRecord.java
void
rrFromWire(DNSInput in) throws IOException {
}
// in org/xbill/DNS/EmptyRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
}
// in org/xbill/DNS/PXRecord.java
void
rrFromWire(DNSInput in) throws IOException {
preference = in.readU16();
map822 = new Name(in);
mapX400 = new Name(in);
}
// in org/xbill/DNS/PXRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
preference = st.getUInt16();
map822 = st.getName(origin);
mapX400 = st.getName(origin);
}
// in org/xbill/DNS/IPSECKEYRecord.java
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();
}
// in org/xbill/DNS/IPSECKEYRecord.java
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);
}
// in org/xbill/DNS/SRVRecord.java
void
rrFromWire(DNSInput in) throws IOException {
priority = in.readU16();
weight = in.readU16();
port = in.readU16();
target = new Name(in);
}
// in org/xbill/DNS/SRVRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
priority = st.getUInt16();
weight = st.getUInt16();
port = st.getUInt16();
target = st.getName(origin);
}
// in org/xbill/DNS/Zone.java
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");
}
// in org/xbill/DNS/Zone.java
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);
}
// in org/xbill/DNS/Zone.java
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();
}
// in org/xbill/DNS/GPOSRecord.java
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());
}
}
// in org/xbill/DNS/GPOSRecord.java
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());
}
}
// in org/xbill/DNS/KEYRecord.java
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();
}
// in org/xbill/DNS/LOCRecord.java
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();
}
// in org/xbill/DNS/LOCRecord.java
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;
}
// in org/xbill/DNS/LOCRecord.java
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);
}
}
// in org/xbill/DNS/LOCRecord.java
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);
}
// in org/xbill/DNS/SOARecord.java
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();
}
// in org/xbill/DNS/SOARecord.java
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();
}
// in org/xbill/DNS/X25Record.java
void
rrFromWire(DNSInput in) throws IOException {
address = in.readCountedString();
}
// in org/xbill/DNS/X25Record.java
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);
}
// in org/xbill/DNS/EDNSOption.java
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;
}
// in org/xbill/DNS/EDNSOption.java
public static EDNSOption
fromWire(byte [] b) throws IOException {
return fromWire(new DNSInput(b));
}
// in org/xbill/DNS/EDNSOption.java
public byte []
toWire() throws IOException {
DNSOutput out = new DNSOutput();
toWire(out);
return out.toByteArray();
}
// in org/xbill/DNS/UNKRecord.java
void
rrFromWire(DNSInput in) throws IOException {
data = in.readByteArray();
}
// in org/xbill/DNS/UNKRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
throw st.exception("invalid unknown RR encoding");
}
// in org/xbill/DNS/U16NameBase.java
void
rrFromWire(DNSInput in) throws IOException {
u16Field = in.readU16();
nameField = new Name(in);
}
// in org/xbill/DNS/U16NameBase.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
u16Field = st.getUInt16();
nameField = st.getName(origin);
}
// in org/xbill/DNS/ZoneTransferIn.java
private void
openConnection() throws IOException {
long endTime = System.currentTimeMillis() + timeout;
client = new TCPClient(endTime);
if (localAddress != null)
client.bind(localAddress);
client.connect(address);
}
// in org/xbill/DNS/ZoneTransferIn.java
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);
}
// in org/xbill/DNS/ZoneTransferIn.java
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");
}
}
// in org/xbill/DNS/ZoneTransferIn.java
public void
run(ZoneTransferHandler handler) throws IOException, ZoneTransferException {
this.handler = handler;
try {
openConnection();
doxfr();
}
finally {
closeConnection();
}
}
// in org/xbill/DNS/ZoneTransferIn.java
public List
run() throws IOException, ZoneTransferException {
BasicHandler handler = new BasicHandler();
run(handler);
if (handler.axfr != null)
return handler.axfr;
return handler.ixfr;
}
// in org/xbill/DNS/TCPClient.java
void
bind(SocketAddress addr) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
channel.socket().bind(addr);
}
// in org/xbill/DNS/TCPClient.java
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);
}
}
// in org/xbill/DNS/TCPClient.java
void
send(byte [] data) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
verboseLog("TCP write", 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);
}
}
// in org/xbill/DNS/TCPClient.java
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;
}
// in org/xbill/DNS/TCPClient.java
byte []
recv() throws IOException {
byte [] buf = _recv(2);
int length = ((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF);
byte [] data = _recv(length);
verboseLog("TCP read", data);
return data;
}
// in org/xbill/DNS/TCPClient.java
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();
}
}
// in org/xbill/DNS/TCPClient.java
static byte []
sendrecv(SocketAddress addr, byte [] data, long endTime) throws IOException {
return sendrecv(null, addr, data, endTime);
}
// in org/xbill/DNS/OPTRecord.java
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);
}
}
// in org/xbill/DNS/OPTRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
throw st.exception("no text format defined for OPT");
}
// in org/xbill/DNS/UDPClient.java
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) {
}
}
}
// in org/xbill/DNS/UDPClient.java
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;
}
}
// in org/xbill/DNS/UDPClient.java
void
connect(SocketAddress addr) throws IOException {
if (!bound)
bind(null);
DatagramChannel channel = (DatagramChannel) key.channel();
channel.connect(addr);
}
// in org/xbill/DNS/UDPClient.java
void
send(byte [] data) throws IOException {
DatagramChannel channel = (DatagramChannel) key.channel();
verboseLog("UDP write", data);
channel.write(ByteBuffer.wrap(data));
}
// in org/xbill/DNS/UDPClient.java
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", data);
return data;
}
// in org/xbill/DNS/UDPClient.java
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();
}
}
// in org/xbill/DNS/UDPClient.java
static byte []
sendrecv(SocketAddress addr, byte [] data, int max, long endTime)
throws IOException
{
return sendrecv(null, addr, data, max, endTime);
}
// in org/xbill/DNS/Update.java
public void
present(Name name, int type, String record) throws IOException {
newPrereq(Record.fromString(name, type, dclass, 0, record, origin));
}
// in org/xbill/DNS/Update.java
public void
present(Name name, int type, Tokenizer tokenizer) throws IOException {
newPrereq(Record.fromString(name, type, dclass, 0, tokenizer, origin));
}
// in org/xbill/DNS/Update.java
public void
add(Name name, int type, long ttl, String record) throws IOException {
newUpdate(Record.fromString(name, type, dclass, ttl, record, origin));
}
// in org/xbill/DNS/Update.java
public void
add(Name name, int type, long ttl, Tokenizer tokenizer) throws IOException {
newUpdate(Record.fromString(name, type, dclass, ttl, tokenizer,
origin));
}
// in org/xbill/DNS/Update.java
public void
delete(Name name, int type, String record) throws IOException {
newUpdate(Record.fromString(name, type, DClass.NONE, 0, record,
origin));
}
// in org/xbill/DNS/Update.java
public void
delete(Name name, int type, Tokenizer tokenizer) throws IOException {
newUpdate(Record.fromString(name, type, DClass.NONE, 0, tokenizer,
origin));
}
// in org/xbill/DNS/Update.java
public void
replace(Name name, int type, long ttl, String record) throws IOException {
delete(name, type);
add(name, type, ttl, record);
}
// in org/xbill/DNS/Update.java
public void
replace(Name name, int type, long ttl, Tokenizer tokenizer) throws IOException
{
delete(name, type);
add(name, type, ttl, tokenizer);
}
// in org/xbill/DNS/DSRecord.java
void
rrFromWire(DNSInput in) throws IOException {
footprint = in.readU16();
alg = in.readU8();
digestid = in.readU8();
digest = in.readByteArray();
}
// in org/xbill/DNS/DSRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
footprint = st.getUInt16();
alg = st.getUInt8();
digestid = st.getUInt8();
digest = st.getHex();
}
// in org/xbill/DNS/MINFORecord.java
void
rrFromWire(DNSInput in) throws IOException {
responsibleAddress = new Name(in);
errorAddress = new Name(in);
}
// in org/xbill/DNS/MINFORecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
responsibleAddress = st.getName(origin);
errorAddress = st.getName(origin);
}
// in org/xbill/DNS/NSAPRecord.java
void
rrFromWire(DNSInput in) throws IOException {
address = in.readByteArray();
}
// in org/xbill/DNS/NSAPRecord.java
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);
}
// in org/xbill/DNS/WKSRecord.java
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(new Integer(i * 8 + j));
}
}
}
services = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
services[i] = ((Integer) list.get(i)).intValue();
}
}
// in org/xbill/DNS/WKSRecord.java
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(new Integer(service));
}
st.unget();
services = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
services[i] = ((Integer) list.get(i)).intValue();
}
}
// in org/xbill/DNS/SIGBase.java
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();
}
// in org/xbill/DNS/SIGBase.java
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();
}
// in org/xbill/DNS/NSECRecord.java
void
rrFromWire(DNSInput in) throws IOException {
next = new Name(in);
types = new TypeBitmap(in);
}
// in org/xbill/DNS/NSECRecord.java
void
rdataFromString(Tokenizer st, Name origin) throws IOException {
next = st.getName(origin);
types = new TypeBitmap(st);
}
// in org/xbill/DNS/NSEC3Record.java
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);
}
// in org/xbill/DNS/NSEC3Record.java
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);
}
// in org/xbill/DNS/NAPTRRecord.java
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);
}
// in org/xbill/DNS/NAPTRRecord.java
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);
}