1// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) 2 3package org.xbill.DNS; 4 5import java.io.*; 6import java.util.*; 7 8/** 9 * A helper class for constructing dynamic DNS (DDNS) update messages. 10 * 11 * @author Brian Wellington 12 */ 13 14public class Update extends Message { 15 16private Name origin; 17private 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 */ 24public 25Update(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 */ 41public 42Update(Name zone) { 43 this(zone, DClass.IN); 44} 45 46private void 47newPrereq(Record rec) { 48 addRecord(rec, Section.PREREQ); 49} 50 51private void 52newUpdate(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 */ 60public void 61present(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 */ 69public void 70present(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 */ 82public void 83present(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 */ 95public void 96present(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 */ 106public void 107present(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 */ 115public void 116absent(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 */ 124public void 125absent(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 */ 134public void 135add(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 */ 144public void 145add(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 */ 153public void 154add(Record record) { 155 newUpdate(record); 156} 157 158/** 159 * Indicates that the records should be inserted into the zone. 160 */ 161public void 162add(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 */ 171public void 172add(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 */ 181public void 182delete(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 */ 190public void 191delete(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 */ 200public void 201delete(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 */ 211public void 212delete(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 */ 220public void 221delete(Record record) { 222 newUpdate(record.withDClass(DClass.NONE, 0)); 223} 224 225/** 226 * Indicates that the records should be deleted from the zone. 227 */ 228public void 229delete(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 */ 238public void 239delete(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 */ 250public void 251replace(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 */ 262public void 263replace(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 */ 273public void 274replace(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 */ 283public void 284replace(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 */ 293public void 294replace(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