io.milton.dns.record.EDNSOption Maven / Gradle / Ivy
/*
* Copied from the DnsJava project
*
* Copyright (c) 1998-2011, Brian Wellington.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package io.milton.dns.record;
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 <[email protected]>, 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 final 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() {
StringBuilder sb = new StringBuilder();
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.
*/
public 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.
*/
public 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 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 (byte b : array) hashval += ((hashval << 3) + (b & 0xFF));
return hashval;
}
abstract String optionToString();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy