1 // Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org)
2
3 package org.xbill.DNS;
4
5 import java.io.*;
6 import java.util.*;
7
8 /**
9 * A helper class for constructing dynamic DNS (DDNS) update messages.
10 *
11 * @author Brian Wellington
12 */
13
14 public class Update extends Message {
15
16 private Name origin;
17 private int dclass;
18
19 /**
20 * Creates an update message.
21 * @param zone The name of the zone being updated.
22 * @param dclass The class of the zone being updated.
23 */
24 public
Update(Name zone, int dclass)25 Update(Name zone, int dclass) {
26 super();
27 if (!zone.isAbsolute())
28 throw new RelativeNameException(zone);
29 DClass.check(dclass);
30 getHeader().setOpcode(Opcode.UPDATE);
31 Record soa = Record.newRecord(zone, Type.SOA, DClass.IN);
32 addRecord(soa, Section.QUESTION);
33 this.origin = zone;
34 this.dclass = dclass;
35 }
36
37 /**
38 * Creates an update message. The class is assumed to be IN.
39 * @param zone The name of the zone being updated.
40 */
41 public
Update(Name zone)42 Update(Name zone) {
43 this(zone, DClass.IN);
44 }
45
46 private void
newPrereq(Record rec)47 newPrereq(Record rec) {
48 addRecord(rec, Section.PREREQ);
49 }
50
51 private void
newUpdate(Record rec)52 newUpdate(Record rec) {
53 addRecord(rec, Section.UPDATE);
54 }
55
56 /**
57 * Inserts a prerequisite that the specified name exists; that is, there
58 * exist records with the given name in the zone.
59 */
60 public void
present(Name name)61 present(Name name) {
62 newPrereq(Record.newRecord(name, Type.ANY, DClass.ANY, 0));
63 }
64
65 /**
66 * Inserts a prerequisite that the specified rrset exists; that is, there
67 * exist records with the given name and type in the zone.
68 */
69 public void
present(Name name, int type)70 present(Name name, int type) {
71 newPrereq(Record.newRecord(name, type, DClass.ANY, 0));
72 }
73
74 /**
75 * Parses a record from the string, and inserts a prerequisite that the
76 * record exists. Due to the way value-dependent prequisites work, the
77 * condition that must be met is that the set of all records with the same
78 * and type in the update message must be identical to the set of all records
79 * with that name and type on the server.
80 * @throws IOException The record could not be parsed.
81 */
82 public void
present(Name name, int type, String record)83 present(Name name, int type, String record) throws IOException {
84 newPrereq(Record.fromString(name, type, dclass, 0, record, origin));
85 }
86
87 /**
88 * Parses a record from the tokenizer, and inserts a prerequisite that the
89 * record exists. Due to the way value-dependent prequisites work, the
90 * condition that must be met is that the set of all records with the same
91 * and type in the update message must be identical to the set of all records
92 * with that name and type on the server.
93 * @throws IOException The record could not be parsed.
94 */
95 public void
present(Name name, int type, Tokenizer tokenizer)96 present(Name name, int type, Tokenizer tokenizer) throws IOException {
97 newPrereq(Record.fromString(name, type, dclass, 0, tokenizer, origin));
98 }
99
100 /**
101 * Inserts a prerequisite that the specified record exists. Due to the way
102 * value-dependent prequisites work, the condition that must be met is that
103 * the set of all records with the same and type in the update message must
104 * be identical to the set of all records with that name and type on the server.
105 */
106 public void
present(Record record)107 present(Record record) {
108 newPrereq(record);
109 }
110
111 /**
112 * Inserts a prerequisite that the specified name does not exist; that is,
113 * there are no records with the given name in the zone.
114 */
115 public void
absent(Name name)116 absent(Name name) {
117 newPrereq(Record.newRecord(name, Type.ANY, DClass.NONE, 0));
118 }
119
120 /**
121 * Inserts a prerequisite that the specified rrset does not exist; that is,
122 * there are no records with the given name and type in the zone.
123 */
124 public void
absent(Name name, int type)125 absent(Name name, int type) {
126 newPrereq(Record.newRecord(name, type, DClass.NONE, 0));
127 }
128
129 /**
130 * Parses a record from the string, and indicates that the record
131 * should be inserted into the zone.
132 * @throws IOException The record could not be parsed.
133 */
134 public void
add(Name name, int type, long ttl, String record)135 add(Name name, int type, long ttl, String record) throws IOException {
136 newUpdate(Record.fromString(name, type, dclass, ttl, record, origin));
137 }
138
139 /**
140 * Parses a record from the tokenizer, and indicates that the record
141 * should be inserted into the zone.
142 * @throws IOException The record could not be parsed.
143 */
144 public void
add(Name name, int type, long ttl, Tokenizer tokenizer)145 add(Name name, int type, long ttl, Tokenizer tokenizer) throws IOException {
146 newUpdate(Record.fromString(name, type, dclass, ttl, tokenizer,
147 origin));
148 }
149
150 /**
151 * Indicates that the record should be inserted into the zone.
152 */
153 public void
add(Record record)154 add(Record record) {
155 newUpdate(record);
156 }
157
158 /**
159 * Indicates that the records should be inserted into the zone.
160 */
161 public void
add(Record [] records)162 add(Record [] records) {
163 for (int i = 0; i < records.length; i++)
164 add(records[i]);
165 }
166
167 /**
168 * Indicates that all of the records in the rrset should be inserted into the
169 * zone.
170 */
171 public void
add(RRset rrset)172 add(RRset rrset) {
173 for (Iterator it = rrset.rrs(); it.hasNext(); )
174 add((Record) it.next());
175 }
176
177 /**
178 * Indicates that all records with the given name should be deleted from
179 * the zone.
180 */
181 public void
delete(Name name)182 delete(Name name) {
183 newUpdate(Record.newRecord(name, Type.ANY, DClass.ANY, 0));
184 }
185
186 /**
187 * Indicates that all records with the given name and type should be deleted
188 * from the zone.
189 */
190 public void
delete(Name name, int type)191 delete(Name name, int type) {
192 newUpdate(Record.newRecord(name, type, DClass.ANY, 0));
193 }
194
195 /**
196 * Parses a record from the string, and indicates that the record
197 * should be deleted from the zone.
198 * @throws IOException The record could not be parsed.
199 */
200 public void
delete(Name name, int type, String record)201 delete(Name name, int type, String record) throws IOException {
202 newUpdate(Record.fromString(name, type, DClass.NONE, 0, record,
203 origin));
204 }
205
206 /**
207 * Parses a record from the tokenizer, and indicates that the record
208 * should be deleted from the zone.
209 * @throws IOException The record could not be parsed.
210 */
211 public void
delete(Name name, int type, Tokenizer tokenizer)212 delete(Name name, int type, Tokenizer tokenizer) throws IOException {
213 newUpdate(Record.fromString(name, type, DClass.NONE, 0, tokenizer,
214 origin));
215 }
216
217 /**
218 * Indicates that the specified record should be deleted from the zone.
219 */
220 public void
delete(Record record)221 delete(Record record) {
222 newUpdate(record.withDClass(DClass.NONE, 0));
223 }
224
225 /**
226 * Indicates that the records should be deleted from the zone.
227 */
228 public void
delete(Record [] records)229 delete(Record [] records) {
230 for (int i = 0; i < records.length; i++)
231 delete(records[i]);
232 }
233
234 /**
235 * Indicates that all of the records in the rrset should be deleted from the
236 * zone.
237 */
238 public void
delete(RRset rrset)239 delete(RRset rrset) {
240 for (Iterator it = rrset.rrs(); it.hasNext(); )
241 delete((Record) it.next());
242 }
243
244 /**
245 * Parses a record from the string, and indicates that the record
246 * should be inserted into the zone replacing any other records with the
247 * same name and type.
248 * @throws IOException The record could not be parsed.
249 */
250 public void
replace(Name name, int type, long ttl, String record)251 replace(Name name, int type, long ttl, String record) throws IOException {
252 delete(name, type);
253 add(name, type, ttl, record);
254 }
255
256 /**
257 * Parses a record from the tokenizer, and indicates that the record
258 * should be inserted into the zone replacing any other records with the
259 * same name and type.
260 * @throws IOException The record could not be parsed.
261 */
262 public void
replace(Name name, int type, long ttl, Tokenizer tokenizer)263 replace(Name name, int type, long ttl, Tokenizer tokenizer) throws IOException
264 {
265 delete(name, type);
266 add(name, type, ttl, tokenizer);
267 }
268
269 /**
270 * Indicates that the record should be inserted into the zone replacing any
271 * other records with the same name and type.
272 */
273 public void
replace(Record record)274 replace(Record record) {
275 delete(record.getName(), record.getType());
276 add(record);
277 }
278
279 /**
280 * Indicates that the records should be inserted into the zone replacing any
281 * other records with the same name and type as each one.
282 */
283 public void
replace(Record [] records)284 replace(Record [] records) {
285 for (int i = 0; i < records.length; i++)
286 replace(records[i]);
287 }
288
289 /**
290 * Indicates that all of the records in the rrset should be inserted into the
291 * zone replacing any other records with the same name and type.
292 */
293 public void
replace(RRset rrset)294 replace(RRset rrset) {
295 delete(rrset.getName(), rrset.getType());
296 for (Iterator it = rrset.rrs(); it.hasNext(); )
297 add((Record) it.next());
298 }
299
300 }
301