com.couchbase.client.core.deps.org.xbill.DNS.OPTRecord Maven / Gradle / Ivy
Show all versions of core-io Show documentation
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 1999-2004 Brian Wellington ([email protected])
package com.couchbase.client.core.deps.org.xbill.DNS;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Options - describes Extended DNS (EDNS) properties of a Message. No specific options are defined
* other than those specified in the header. An OPT should be generated by Resolver.
*
* EDNS is a method to extend the DNS protocol while providing backwards compatibility and not
* significantly changing the protocol. This implementation of EDNS is mostly complete at level 0.
*
* @see Message
* @see Resolver
* @see RFC 6891: Extension Mechanisms for DNS
* @author Brian Wellington
*/
public class OPTRecord extends Record {
private List options;
OPTRecord() {}
/**
* Creates an OPT Record. This is normally called by SimpleResolver, but can also be called by a
* server.
*
* @param payloadSize The size of a packet that can be reassembled on the sending host.
* @param xrcode The value of the extended rcode field. This is the upper 16 bits of the full
* rcode.
* @param flags Additional message flags.
* @param version The EDNS version that this DNS implementation supports. This should be 0 for
* dnsjava.
* @param options The options that comprise the data field.
* @see ExtendedFlags
*/
public OPTRecord(int payloadSize, int xrcode, int version, int flags, EDNSOption... options) {
this(payloadSize, xrcode, version, flags);
if (options != null) {
this.options = new ArrayList<>(Arrays.asList(options));
}
}
/**
* Creates an OPT Record. This is normally called by SimpleResolver, but can also be called by a
* server.
*
* @param payloadSize The size of a packet that can be reassembled on the sending host.
* @param xrcode The value of the extended rcode field. This is the upper 16 bits of the full
* rcode.
* @param flags Additional message flags.
* @param version The EDNS version that this DNS implementation supports. This should be 0 for
* dnsjava.
* @param options The list of options that comprise the data field.
* @see ExtendedFlags
*/
public OPTRecord(int payloadSize, int xrcode, int version, int flags, List options) {
this(payloadSize, xrcode, version, flags);
if (options != null) {
this.options = new ArrayList<>(options);
}
}
/**
* Creates an OPT Record with no data. This is normally called by SimpleResolver, but can also be
* called by a server.
*
* @param payloadSize The size of a packet that can be reassembled on the sending host.
* @param xrcode The value of the extended rcode field. This is the upper 16 bits of the full
* rcode.
* @param flags Additional message flags.
* @param version The EDNS version that this DNS implementation supports. This should be 0 for
* dnsjava.
* @see ExtendedFlags
*/
public OPTRecord(int payloadSize, int xrcode, int version, int flags) {
super(Name.root, Type.OPT, payloadSize, 0);
checkU16("payloadSize", payloadSize);
checkU8("xrcode", xrcode);
checkU8("version", version);
checkU16("flags", flags);
ttl = ((long) xrcode << 24) + ((long) version << 16) + flags;
}
/**
* Creates an OPT Record with no data. This is normally called by SimpleResolver, but can also be
* called by a server.
*/
public OPTRecord(int payloadSize, int xrcode, int version) {
this(payloadSize, xrcode, version, 0);
}
@Override
protected 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);
}
}
@Override
protected void rdataFromString(Tokenizer st, Name origin) throws IOException {
throw st.exception("no text format defined for OPT");
}
/** Converts rdata to a String */
@Override
protected String rrToString() {
StringBuilder sb = new StringBuilder();
if (options != null) {
sb.append(options);
sb.append(" ");
}
sb.append(" ; payload ");
sb.append(getPayloadSize());
sb.append(", xrcode ");
sb.append(getExtendedRcode());
sb.append(", version ");
sb.append(getVersion());
sb.append(", flags ");
sb.append(getFlags());
return sb.toString();
}
/** Converts this record to a String representation */
@Override
public String toString() {
return Name.root + "\t\t\t\t" + Type.string(type) + "\t" + rrToString();
}
void printPseudoSection(StringBuilder sb) {
sb.append(";; OPT PSEUDOSECTION: \n; EDNS: version: ");
sb.append(getVersion());
sb.append("; flags: ");
for (int i = 0; i < 16; i++) {
if ((getFlags() & (1 << (15 - i))) != 0) {
sb.append(ExtendedFlags.stringFromBit(i));
sb.append(" ");
}
}
sb.append("; udp: ").append(getPayloadSize());
if (options != null) {
for (EDNSOption o : options) {
sb.append("\n; ")
.append(EDNSOption.Code.string(o.getCode()))
.append(": ")
.append(o.optionToString());
}
}
}
/** Returns the maximum allowed payload size. */
public int getPayloadSize() {
return dclass;
}
/**
* Returns the extended Rcode
*
* @see Rcode
*/
public int getExtendedRcode() {
return (int) (ttl >>> 24);
}
/** Returns the highest supported EDNS version */
public int getVersion() {
return (int) ((ttl >>> 16) & 0xFF);
}
/** Returns the EDNS flags */
public int getFlags() {
return (int) (ttl & 0xFFFF);
}
@Override
protected void rrToWire(DNSOutput out, Compression c, boolean canonical) {
if (options == null) {
return;
}
for (EDNSOption option : options) {
option.toWire(out);
}
}
/** Gets all options in the OPTRecord. This returns a list of EDNSOptions. */
public List getOptions() {
if (options == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(options);
}
/** Gets all options in the OPTRecord with a specific code. This returns a list of EDNSOptions. */
public List getOptions(int code) {
if (options == null) {
return Collections.emptyList();
}
List list = new ArrayList<>();
for (EDNSOption opt : options) {
if (opt.getCode() == code) {
list.add(opt);
}
}
return list;
}
/**
* Determines if two OPTRecords are identical. This compares the name, type, class, and rdata
* (with names canonicalized). Additionally, because TTLs are relevant for OPT records, the TTLs
* are compared.
*
* @param arg The record to compare to
* @return true if the records are equal, false otherwise.
*/
@Override
public boolean equals(final Object arg) {
return super.equals(arg) && ttl == ((OPTRecord) arg).ttl;
}
@Override
public int hashCode() {
byte[] array = toWireCanonical();
int code = 0;
for (byte b : array) {
code += (code << 3) + (b & 0xFF);
}
return code;
}
}