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