1 // Copyright (c) 1999-2004 Brian Wellington (bwelling (at) xbill.org) 2 3 package org.xbill.DNS; 4 5 import java.io.*; 6 import 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 23 public class OPTRecord extends Record { 24 25 private static final long serialVersionUID = -6254521894809367938L; 26 27 private List options; 28 29 OPTRecord() {} 30 31 Record 32 getObject() { 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 */ 50 public 51 OPTRecord(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 */ 75 public 76 OPTRecord(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 */ 84 public 85 OPTRecord(int payloadSize, int xrcode, int version) { 86 this(payloadSize, xrcode, version, 0, null); 87 } 88 89 void 90 rrFromWire(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 99 void 100 rdataFromString(Tokenizer st, Name origin) throws IOException { 101 throw st.exception("no text format defined for OPT"); 102 } 103 104 /** Converts rdata to a String */ 105 String 106 rrToString() { 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. */ 124 public int 125 getPayloadSize() { 126 return dclass; 127 } 128 129 /** 130 * Returns the extended Rcode 131 * @see Rcode 132 */ 133 public int 134 getExtendedRcode() { 135 return (int)(ttl >>> 24); 136 } 137 138 /** Returns the highest supported EDNS version */ 139 public int 140 getVersion() { 141 return (int)((ttl >>> 16) & 0xFF); 142 } 143 144 /** Returns the EDNS flags */ 145 public int 146 getFlags() { 147 return (int)(ttl & 0xFFFF); 148 } 149 150 void 151 rrToWire(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 */ 164 public List 165 getOptions() { 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 */ 175 public List 176 getOptions(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