1 // Copyright (c) 1999-2004 Brian Wellington (bwelling@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
OPTRecord()29 OPTRecord() {}
30
31 Record
getObject()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
OPTRecord(int payloadSize, int xrcode, int version, int flags, List options)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
OPTRecord(int payloadSize, int xrcode, int version, int flags)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
OPTRecord(int payloadSize, int xrcode, int version)85 OPTRecord(int payloadSize, int xrcode, int version) {
86 this(payloadSize, xrcode, version, 0, null);
87 }
88
89 void
rrFromWire(DNSInput in)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
rdataFromString(Tokenizer st, Name origin)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
rrToString()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
getPayloadSize()125 getPayloadSize() {
126 return dclass;
127 }
128
129 /**
130 * Returns the extended Rcode
131 * @see Rcode
132 */
133 public int
getExtendedRcode()134 getExtendedRcode() {
135 return (int)(ttl >>> 24);
136 }
137
138 /** Returns the highest supported EDNS version */
139 public int
getVersion()140 getVersion() {
141 return (int)((ttl >>> 16) & 0xFF);
142 }
143
144 /** Returns the EDNS flags */
145 public int
getFlags()146 getFlags() {
147 return (int)(ttl & 0xFFFF);
148 }
149
150 void
rrToWire(DNSOutput out, Compression c, boolean canonical)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
getOptions()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
getOptions(int code)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