1// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) 2 3package org.xbill.DNS; 4 5import java.io.*; 6import java.util.*; 7 8/** 9 * Options - describes Extended DNS (EDNS) properties of a Message. 10 * No specific options are defined other than those specified in the 11 * header. An OPT should be generated by Resolver. 12 * 13 * EDNS is a method to extend the DNS protocol while providing backwards 14 * compatibility and not significantly changing the protocol. This 15 * implementation of EDNS is mostly complete at level 0. 16 * 17 * @see Message 18 * @see Resolver 19 * 20 * @author Brian Wellington 21 */ 22 23public class OPTRecord extends Record { 24 25private static final long serialVersionUID = -6254521894809367938L; 26 27private List options; 28 29OPTRecord() {} 30 31Record 32getObject() { 33 return new OPTRecord(); 34} 35 36/** 37 * Creates an OPT Record. This is normally called by SimpleResolver, but can 38 * also be called by a server. 39 * @param payloadSize The size of a packet that can be reassembled on the 40 * sending host. 41 * @param xrcode The value of the extended rcode field. This is the upper 42 * 16 bits of the full rcode. 43 * @param flags Additional message flags. 44 * @param version The EDNS version that this DNS implementation supports. 45 * This should be 0 for dnsjava. 46 * @param options The list of options that comprise the data field. There 47 * are currently no defined options. 48 * @see ExtendedFlags 49 */ 50public 51OPTRecord(int payloadSize, int xrcode, int version, int flags, List options) { 52 super(Name.root, Type.OPT, payloadSize, 0); 53 checkU16("payloadSize", payloadSize); 54 checkU8("xrcode", xrcode); 55 checkU8("version", version); 56 checkU16("flags", flags); 57 ttl = ((long)xrcode << 24) + ((long)version << 16) + flags; 58 if (options != null) { 59 this.options = new ArrayList(options); 60 } 61} 62 63/** 64 * Creates an OPT Record with no data. This is normally called by 65 * SimpleResolver, but can also be called by a server. 66 * @param payloadSize The size of a packet that can be reassembled on the 67 * sending host. 68 * @param xrcode The value of the extended rcode field. This is the upper 69 * 16 bits of the full rcode. 70 * @param flags Additional message flags. 71 * @param version The EDNS version that this DNS implementation supports. 72 * This should be 0 for dnsjava. 73 * @see ExtendedFlags 74 */ 75public 76OPTRecord(int payloadSize, int xrcode, int version, int flags) { 77 this(payloadSize, xrcode, version, flags, null); 78} 79 80/** 81 * Creates an OPT Record with no data. This is normally called by 82 * SimpleResolver, but can also be called by a server. 83 */ 84public 85OPTRecord(int payloadSize, int xrcode, int version) { 86 this(payloadSize, xrcode, version, 0, null); 87} 88 89void 90rrFromWire(DNSInput in) throws IOException { 91 if (in.remaining() > 0) 92 options = new ArrayList(); 93 while (in.remaining() > 0) { 94 EDNSOption option = EDNSOption.fromWire(in); 95 options.add(option); 96 } 97} 98 99void 100rdataFromString(Tokenizer st, Name origin) throws IOException { 101 throw st.exception("no text format defined for OPT"); 102} 103 104/** Converts rdata to a String */ 105String 106rrToString() { 107 StringBuffer sb = new StringBuffer(); 108 if (options != null) { 109 sb.append(options); 110 sb.append(" "); 111 } 112 sb.append(" ; payload "); 113 sb.append(getPayloadSize()); 114 sb.append(", xrcode "); 115 sb.append(getExtendedRcode()); 116 sb.append(", version "); 117 sb.append(getVersion()); 118 sb.append(", flags "); 119 sb.append(getFlags()); 120 return sb.toString(); 121} 122 123/** Returns the maximum allowed payload size. */ 124public int 125getPayloadSize() { 126 return dclass; 127} 128 129/** 130 * Returns the extended Rcode 131 * @see Rcode 132 */ 133public int 134getExtendedRcode() { 135 return (int)(ttl >>> 24); 136} 137 138/** Returns the highest supported EDNS version */ 139public int 140getVersion() { 141 return (int)((ttl >>> 16) & 0xFF); 142} 143 144/** Returns the EDNS flags */ 145public int 146getFlags() { 147 return (int)(ttl & 0xFFFF); 148} 149 150void 151rrToWire(DNSOutput out, Compression c, boolean canonical) { 152 if (options == null) 153 return; 154 Iterator it = options.iterator(); 155 while (it.hasNext()) { 156 EDNSOption option = (EDNSOption) it.next(); 157 option.toWire(out); 158 } 159} 160 161/** 162 * Gets all options in the OPTRecord. This returns a list of EDNSOptions. 163 */ 164public List 165getOptions() { 166 if (options == null) 167 return Collections.EMPTY_LIST; 168 return Collections.unmodifiableList(options); 169} 170 171/** 172 * Gets all options in the OPTRecord with a specific code. This returns a list 173 * of EDNSOptions. 174 */ 175public List 176getOptions(int code) { 177 if (options == null) 178 return Collections.EMPTY_LIST; 179 List list = Collections.EMPTY_LIST; 180 for (Iterator it = options.iterator(); it.hasNext(); ) { 181 EDNSOption opt = (EDNSOption) it.next(); 182 if (opt.getCode() == code) { 183 if (list == Collections.EMPTY_LIST) 184 list = new ArrayList(); 185 list.add(opt); 186 } 187 } 188 return list; 189} 190 191} 192