// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) package org.xbill.DNS; import java.io.*; import java.util.*; /** * Options - describes Extended DNS (EDNS) properties of a Message. * No specific options are defined other than those specified in the * header. An OPT should be generated by Resolver. * * EDNS is a method to extend the DNS protocol while providing backwards * compatibility and not significantly changing the protocol. This * implementation of EDNS is mostly complete at level 0. * * @see Message * @see Resolver * * @author Brian Wellington */ public class OPTRecord extends Record { private static final long serialVersionUID = -6254521894809367938L; private List options; OPTRecord() {} Record getObject() { return new OPTRecord(); } /** * Creates an OPT Record. This is normally called by SimpleResolver, but can * also be called by a server. * @param payloadSize The size of a packet that can be reassembled on the * sending host. * @param xrcode The value of the extended rcode field. This is the upper * 16 bits of the full rcode. * @param flags Additional message flags. * @param version The EDNS version that this DNS implementation supports. * This should be 0 for dnsjava. * @param options The list of options that comprise the data field. There * are currently no defined options. * @see ExtendedFlags */ public OPTRecord(int payloadSize, int xrcode, int version, int flags, List options) { super(Name.root, Type.OPT, payloadSize, 0); checkU16("payloadSize", payloadSize); checkU8("xrcode", xrcode); checkU8("version", version); checkU16("flags", flags); ttl = ((long)xrcode << 24) + ((long)version << 16) + flags; if (options != null) { this.options = new ArrayList(options); } } /** * Creates an OPT Record with no data. This is normally called by * SimpleResolver, but can also be called by a server. * @param payloadSize The size of a packet that can be reassembled on the * sending host. * @param xrcode The value of the extended rcode field. This is the upper * 16 bits of the full rcode. * @param flags Additional message flags. * @param version The EDNS version that this DNS implementation supports. * This should be 0 for dnsjava. * @see ExtendedFlags */ public OPTRecord(int payloadSize, int xrcode, int version, int flags) { this(payloadSize, xrcode, version, flags, null); } /** * Creates an OPT Record with no data. This is normally called by * SimpleResolver, but can also be called by a server. */ public OPTRecord(int payloadSize, int xrcode, int version) { this(payloadSize, xrcode, version, 0, null); } void rrFromWire(DNSInput in) throws IOException { if (in.remaining() > 0) options = new ArrayList(); while (in.remaining() > 0) { EDNSOption option = EDNSOption.fromWire(in); options.add(option); } } void rdataFromString(Tokenizer st, Name origin) throws IOException { throw st.exception("no text format defined for OPT"); } /** Converts rdata to a String */ String rrToString() { StringBuffer sb = new StringBuffer(); if (options != null) { sb.append(options); sb.append(" "); } sb.append(" ; payload "); sb.append(getPayloadSize()); sb.append(", xrcode "); sb.append(getExtendedRcode()); sb.append(", version "); sb.append(getVersion()); sb.append(", flags "); sb.append(getFlags()); return sb.toString(); } /** Returns the maximum allowed payload size. */ public int getPayloadSize() { return dclass; } /** * Returns the extended Rcode * @see Rcode */ public int getExtendedRcode() { return (int)(ttl >>> 24); } /** Returns the highest supported EDNS version */ public int getVersion() { return (int)((ttl >>> 16) & 0xFF); } /** Returns the EDNS flags */ public int getFlags() { return (int)(ttl & 0xFFFF); } void rrToWire(DNSOutput out, Compression c, boolean canonical) { if (options == null) return; Iterator it = options.iterator(); while (it.hasNext()) { EDNSOption option = (EDNSOption) it.next(); option.toWire(out); } } /** * Gets all options in the OPTRecord. This returns a list of EDNSOptions. */ public List getOptions() { if (options == null) return Collections.EMPTY_LIST; return Collections.unmodifiableList(options); } /** * Gets all options in the OPTRecord with a specific code. This returns a list * of EDNSOptions. */ public List getOptions(int code) { if (options == null) return Collections.EMPTY_LIST; List list = Collections.EMPTY_LIST; for (Iterator it = options.iterator(); it.hasNext(); ) { EDNSOption opt = (EDNSOption) it.next(); if (opt.getCode() == code) { if (list == Collections.EMPTY_LIST) list = new ArrayList(); list.add(opt); } } return list; } }