1
1
/*******************************************************************************
2
*Copyright (c) 2009 Eucalyptus Systems, Inc.
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, only version 3 of the License.
9
* This file is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* You should have received a copy of the GNU General Public License along
15
* with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Please contact Eucalyptus Systems, Inc., 130 Castilian
18
* Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
19
* if you need additional information or have any questions.
21
* This file may incorporate work covered under the following copyright and
24
* Software License Agreement (BSD License)
26
* Copyright (c) 2008, Regents of the University of California
27
* All rights reserved.
29
* Redistribution and use of this software in source and binary forms, with
30
* or without modification, are permitted provided that the following
33
* Redistributions of source code must retain the above copyright notice,
34
* this list of conditions and the following disclaimer.
36
* Redistributions in binary form must reproduce the above copyright
37
* notice, this list of conditions and the following disclaimer in the
38
* documentation and/or other materials provided with the distribution.
40
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
41
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
42
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
43
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
44
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
46
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
47
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
48
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
49
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
51
* THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
52
* LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
53
* SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
54
* IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
55
* BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
56
* THE REGENTSā DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
57
* OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
58
* WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
59
* ANY SUCH LICENSES OR RIGHTS.
60
*******************************************************************************/
2
*Copyright (c) 2009 Eucalyptus Systems, Inc.
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, only version 3 of the License.
9
* This file is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* You should have received a copy of the GNU General Public License along
15
* with this program. If not, see <http://www.gnu.org/licenses/>.
17
* Please contact Eucalyptus Systems, Inc., 130 Castilian
18
* Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
19
* if you need additional information or have any questions.
21
* This file may incorporate work covered under the following copyright and
24
* Software License Agreement (BSD License)
26
* Copyright (c) 2008, Regents of the University of California
27
* All rights reserved.
29
* Redistribution and use of this software in source and binary forms, with
30
* or without modification, are permitted provided that the following
33
* Redistributions of source code must retain the above copyright notice,
34
* this list of conditions and the following disclaimer.
36
* Redistributions in binary form must reproduce the above copyright
37
* notice, this list of conditions and the following disclaimer in the
38
* documentation and/or other materials provided with the distribution.
40
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
41
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
42
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
43
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
44
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
46
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
47
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
48
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
49
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
51
* THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
52
* LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
53
* SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
54
* IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
55
* BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
56
* THE REGENTSā DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
57
* OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
58
* WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
59
* ANY SUCH LICENSES OR RIGHTS.
60
*******************************************************************************/
63
63
* Author: Neil Soman neil@eucalyptus.com
104
104
public class ConnectionHandler extends Thread {
106
static final int FLAG_DNSSECOK = 1;
107
static final int FLAG_SIGONLY = 2;
109
Map caches = new ConcurrentHashMap();
113
generateReply(Message query, byte [] in, int length, Socket s)
123
header = query.getHeader();
124
if (header.getFlag(Flags.QR))
126
if (header.getRcode() != Rcode.NOERROR)
127
return errorMessage(query, Rcode.FORMERR);
128
if (header.getOpcode() != Opcode.QUERY)
129
return errorMessage(query, Rcode.NOTIMP);
131
Record queryRecord = query.getQuestion();
133
TSIGRecord queryTSIG = query.getTSIG();
135
/* if (queryTSIG != null) {
106
static final int FLAG_DNSSECOK = 1;
107
static final int FLAG_SIGONLY = 2;
109
Map caches = new ConcurrentHashMap();
113
generateReply(Message query, byte [] in, int length, Socket s)
123
header = query.getHeader();
124
if (header.getFlag(Flags.QR))
126
if (header.getRcode() != Rcode.NOERROR)
127
return errorMessage(query, Rcode.FORMERR);
128
if (header.getOpcode() != Opcode.QUERY)
129
return errorMessage(query, Rcode.NOTIMP);
131
Record queryRecord = query.getQuestion();
133
TSIGRecord queryTSIG = query.getTSIG();
135
/* if (queryTSIG != null) {
136
136
tsig = (TSIG) TSIGs.get(queryTSIG.getName());
137
137
if (tsig == null ||
138
138
tsig.verify(query, in, length, null) != Rcode.NOERROR)
139
139
return formerrMessage(in);
142
OPTRecord queryOPT = query.getOPT();
143
if (queryOPT != null && queryOPT.getVersion() > 0)
148
else if (queryOPT != null)
149
maxLength = Math.max(queryOPT.getPayloadSize(), 512);
153
if (queryOPT != null && (queryOPT.getFlags() & ExtendedFlags.DO) != 0)
154
flags = FLAG_DNSSECOK;
156
Message response = new Message(query.getHeader().getID());
157
response.getHeader().setFlag(Flags.QR);
158
if (query.getHeader().getFlag(Flags.RD))
159
response.getHeader().setFlag(Flags.RD);
160
response.addRecord(queryRecord, Section.QUESTION);
162
Name name = queryRecord.getName();
163
int type = queryRecord.getType();
164
int dclass = queryRecord.getDClass();
165
/* if (type == Type.AXFR && s != null)
142
OPTRecord queryOPT = query.getOPT();
143
if (queryOPT != null && queryOPT.getVersion() > 0)
148
else if (queryOPT != null)
149
maxLength = Math.max(queryOPT.getPayloadSize(), 512);
153
if (queryOPT != null && (queryOPT.getFlags() & ExtendedFlags.DO) != 0)
154
flags = FLAG_DNSSECOK;
156
Message response = new Message(query.getHeader().getID());
157
response.getHeader().setFlag(Flags.QR);
158
if (query.getHeader().getFlag(Flags.RD))
159
response.getHeader().setFlag(Flags.RD);
160
if(queryRecord != null) {
161
response.addRecord(queryRecord, Section.QUESTION);
163
Name name = queryRecord.getName();
164
int type = queryRecord.getType();
165
int dclass = queryRecord.getDClass();
167
/* if (type == Type.AXFR && s != null)
166
168
return doAXFR(name, query, tsig, queryTSIG, s);
167
*/ if (!Type.isRR(type) && type != Type.ANY)
168
return errorMessage(query, Rcode.NOTIMP);
170
byte rcode = addAnswer(response, name, type, dclass, 0, flags);
171
if (rcode != Rcode.NOERROR && rcode != Rcode.NXDOMAIN)
172
return errorMessage(query, rcode);
174
addAdditional(response, flags);
176
if (queryOPT != null) {
177
int optflags = (flags == FLAG_DNSSECOK) ? ExtendedFlags.DO : 0;
178
OPTRecord opt = new OPTRecord((short)4096, rcode, (byte)0,
180
response.addRecord(opt, Section.ADDITIONAL);
183
response.setTSIG(tsig, Rcode.NOERROR, queryTSIG);
184
return response.toWire(maxLength);
188
findBestZone(Name name) {
189
Zone foundzone = null;
190
foundzone = (Zone) ZoneManager.getZone(name);
191
if (foundzone != null)
193
int labels = name.labels();
194
for (int i = 1; i < labels; i++) {
195
Name tname = new Name(name, i);
196
foundzone = (Zone) ZoneManager.getZone(tname);
197
if (foundzone != null)
204
findExactMatch(Name name, int type, int dclass, boolean glue) {
205
Zone zone = findBestZone(name);
207
return zone.findExactMatch(name, type);
210
Cache cache = getCache(dclass);
212
rrsets = cache.findAnyRecords(name, type);
214
rrsets = cache.findRecords(name, type);
218
return rrsets[0]; /* not quite right */
223
addGlue(Message response, Name name, int flags) {
224
RRset a = findExactMatch(name, Type.A, DClass.IN, true);
227
addRRset(name, response, a, Section.ADDITIONAL, flags);
231
addAdditional2(Message response, int section, int flags) {
232
Record [] records = response.getSectionArray(section);
233
for (int i = 0; i < records.length; i++) {
234
Record r = records[i];
235
Name glueName = r.getAdditionalName();
236
if (glueName != null)
237
addGlue(response, glueName, flags);
242
addAdditional(Message response, int flags) {
243
addAdditional2(response, Section.ANSWER, flags);
244
addAdditional2(response, Section.AUTHORITY, flags);
248
addAnswer(Message response, Name name, int type, int dclass,
249
int iterations, int flags)
252
byte rcode = Rcode.NOERROR;
255
return Rcode.NOERROR;
257
if (type == Type.SIG || type == Type.RRSIG) {
259
flags |= FLAG_SIGONLY;
262
Zone zone = findBestZone(name);
264
sr = zone.findRecords(name, type);
266
Cache cache = getCache(dclass);
267
sr = cache.lookupRecords(name, type, Credibility.NORMAL);
270
if (sr.isUnknown()) {
271
addCacheNS(response, getCache(dclass), name);
273
if (sr.isNXDOMAIN()) {
274
response.getHeader().setRcode(Rcode.NXDOMAIN);
276
addSOA(response, zone);
278
response.getHeader().setFlag(Flags.AA);
280
rcode = Rcode.NXDOMAIN;
282
else if (sr.isNXRRSET()) {
284
addSOA(response, zone);
286
response.getHeader().setFlag(Flags.AA);
289
else if (sr.isDelegation()) {
290
RRset nsRecords = sr.getNS();
291
addRRset(nsRecords.getName(), response, nsRecords,
292
Section.AUTHORITY, flags);
294
else if (sr.isCNAME()) {
295
CNAMERecord cname = sr.getCNAME();
296
RRset rrset = new RRset(cname);
297
addRRset(name, response, rrset, Section.ANSWER, flags);
298
if (zone != null && iterations == 0)
299
response.getHeader().setFlag(Flags.AA);
300
rcode = addAnswer(response, cname.getTarget(),
301
type, dclass, iterations + 1, flags);
303
else if (sr.isDNAME()) {
304
DNAMERecord dname = sr.getDNAME();
305
RRset rrset = new RRset(dname);
306
addRRset(name, response, rrset, Section.ANSWER, flags);
309
newname = name.fromDNAME(dname);
311
catch (NameTooLongException e) {
312
return Rcode.YXDOMAIN;
314
rrset = new RRset(new CNAMERecord(name, dclass, 0, newname));
315
addRRset(name, response, rrset, Section.ANSWER, flags);
316
if (zone != null && iterations == 0)
317
response.getHeader().setFlag(Flags.AA);
318
rcode = addAnswer(response, newname, type, dclass,
319
iterations + 1, flags);
321
else if (sr.isSuccessful()) {
322
RRset [] rrsets = sr.answers();
323
for (int i = 0; i < rrsets.length; i++)
324
addRRset(name, response, rrsets[i],
325
Section.ANSWER, flags);
327
addNS(response, zone, flags);
329
response.getHeader().setFlag(Flags.AA);
332
addCacheNS(response, getCache(dclass), name);
339
addSOA(Message response, Zone zone) {
340
response.addRecord(zone.getSOA(), Section.AUTHORITY);
344
addNS(Message response, Zone zone, int flags) {
345
RRset nsRecords = zone.getNS();
346
addRRset(nsRecords.getName(), response, nsRecords,
347
Section.AUTHORITY, flags);
351
addCacheNS(Message response, Cache cache, Name name) {
352
SetResponse sr = cache.lookupRecords(name, Type.NS, Credibility.HINT);
353
if (!sr.isDelegation())
355
RRset nsRecords = sr.getNS();
356
Iterator it = nsRecords.rrs();
357
while (it.hasNext()) {
358
Record r = (Record) it.next();
359
response.addRecord(r, Section.AUTHORITY);
365
doAXFR(Name name, Message query, TSIG tsig, TSIGRecord qtsig, Socket s) {
366
Zone zone = (Zone) ZoneManager.getZone(name);
367
boolean first = true;
369
return errorMessage(query, Rcode.REFUSED);
370
Iterator it = zone.AXFR();
372
DataOutputStream dataOut;
373
dataOut = new DataOutputStream(s.getOutputStream());
374
int id = query.getHeader().getID();
375
while (it.hasNext()) {
376
RRset rrset = (RRset) it.next();
377
Message response = new Message(id);
378
Header header = response.getHeader();
379
header.setFlag(Flags.QR);
380
header.setFlag(Flags.AA);
381
addRRset(rrset.getName(), response, rrset,
382
Section.ANSWER, FLAG_DNSSECOK);
384
tsig.applyStream(response, qtsig, first);
385
qtsig = response.getTSIG();
388
byte [] out = response.toWire();
389
dataOut.writeShort(out.length);
393
catch (IOException ex) {
394
System.out.println("AXFR failed");
399
catch (IOException ex) {
405
addRRset(Name name, Message response, RRset rrset, int section, int flags) {
406
for (int s = 1; s <= section; s++)
407
if (response.findRRset(name, rrset.getType(), s))
409
if ((flags & FLAG_SIGONLY) == 0) {
410
Iterator it = rrset.rrs();
411
while (it.hasNext()) {
412
Record r = (Record) it.next();
413
if (r.getName().isWild() && !name.isWild())
414
r = r.withName(name);
415
response.addRecord(r, section);
418
if ((flags & (FLAG_SIGONLY | FLAG_DNSSECOK)) != 0) {
419
Iterator it = rrset.sigs();
420
while (it.hasNext()) {
421
Record r = (Record) it.next();
422
if (r.getName().isWild() && !name.isWild())
423
r = r.withName(name);
424
response.addRecord(r, section);
430
buildErrorMessage(Header header, int rcode, Record question) {
431
Message response = new Message();
432
response.setHeader(header);
433
for (int i = 0; i < 4; i++)
434
response.removeAllRecords(i);
435
if (rcode == Rcode.SERVFAIL)
436
response.addRecord(question, Section.QUESTION);
437
header.setRcode(rcode);
438
return response.toWire();
442
errorMessage(Message query, int rcode) {
443
return buildErrorMessage(query.getHeader(), rcode,
444
query.getQuestion());
448
formerrMessage(byte [] in) {
451
header = new Header(in);
453
catch (IOException e) {
456
return buildErrorMessage(header, Rcode.FORMERR, null);
460
getCache(int dclass) {
461
Cache c = (Cache) caches.get(new Integer(dclass));
463
c = new Cache(dclass);
464
caches.put(new Integer(dclass), c);
169
*/ if (!Type.isRR(type) && type != Type.ANY)
170
return errorMessage(query, Rcode.NOTIMP);
172
byte rcode = addAnswer(response, name, type, dclass, 0, flags);
173
if (rcode != Rcode.NOERROR && rcode != Rcode.NXDOMAIN)
174
return errorMessage(query, rcode);
176
addAdditional(response, flags);
178
if (queryOPT != null) {
179
int optflags = (flags == FLAG_DNSSECOK) ? ExtendedFlags.DO : 0;
180
OPTRecord opt = new OPTRecord((short)4096, rcode, (byte)0,
182
response.addRecord(opt, Section.ADDITIONAL);
185
response.setTSIG(tsig, Rcode.NOERROR, queryTSIG);
186
return response.toWire(maxLength);
190
findBestZone(Name name) {
191
Zone foundzone = null;
192
foundzone = (Zone) ZoneManager.getZone(name);
193
if (foundzone != null)
195
int labels = name.labels();
196
for (int i = 1; i < labels; i++) {
197
Name tname = new Name(name, i);
198
foundzone = (Zone) ZoneManager.getZone(tname);
199
if (foundzone != null)
206
findExactMatch(Name name, int type, int dclass, boolean glue) {
207
Zone zone = findBestZone(name);
209
return zone.findExactMatch(name, type);
212
Cache cache = getCache(dclass);
214
rrsets = cache.findAnyRecords(name, type);
216
rrsets = cache.findRecords(name, type);
220
return rrsets[0]; /* not quite right */
225
addGlue(Message response, Name name, int flags) {
226
RRset a = findExactMatch(name, Type.A, DClass.IN, true);
229
addRRset(name, response, a, Section.ADDITIONAL, flags);
233
addAdditional2(Message response, int section, int flags) {
234
Record [] records = response.getSectionArray(section);
235
for (int i = 0; i < records.length; i++) {
236
Record r = records[i];
237
Name glueName = r.getAdditionalName();
238
if (glueName != null)
239
addGlue(response, glueName, flags);
244
addAdditional(Message response, int flags) {
245
addAdditional2(response, Section.ANSWER, flags);
246
addAdditional2(response, Section.AUTHORITY, flags);
250
addAnswer(Message response, Name name, int type, int dclass,
251
int iterations, int flags)
254
byte rcode = Rcode.NOERROR;
257
return Rcode.NOERROR;
259
if (type == Type.SIG || type == Type.RRSIG) {
261
flags |= FLAG_SIGONLY;
264
Zone zone = findBestZone(name);
266
sr = zone.findRecords(name, type);
268
Cache cache = getCache(dclass);
269
sr = cache.lookupRecords(name, type, Credibility.NORMAL);
272
if (sr.isUnknown()) {
273
addCacheNS(response, getCache(dclass), name);
275
if (sr.isNXDOMAIN()) {
276
response.getHeader().setRcode(Rcode.NXDOMAIN);
278
addSOA(response, zone);
280
response.getHeader().setFlag(Flags.AA);
282
rcode = Rcode.NXDOMAIN;
284
else if (sr.isNXRRSET()) {
286
addSOA(response, zone);
288
response.getHeader().setFlag(Flags.AA);
291
else if (sr.isDelegation()) {
292
RRset nsRecords = sr.getNS();
293
addRRset(nsRecords.getName(), response, nsRecords,
294
Section.AUTHORITY, flags);
296
else if (sr.isCNAME()) {
297
CNAMERecord cname = sr.getCNAME();
298
RRset rrset = new RRset(cname);
299
addRRset(name, response, rrset, Section.ANSWER, flags);
300
if (zone != null && iterations == 0)
301
response.getHeader().setFlag(Flags.AA);
302
rcode = addAnswer(response, cname.getTarget(),
303
type, dclass, iterations + 1, flags);
305
else if (sr.isDNAME()) {
306
DNAMERecord dname = sr.getDNAME();
307
RRset rrset = new RRset(dname);
308
addRRset(name, response, rrset, Section.ANSWER, flags);
311
newname = name.fromDNAME(dname);
313
catch (NameTooLongException e) {
314
return Rcode.YXDOMAIN;
316
if(newname != null) {
317
rrset = new RRset(new CNAMERecord(name, dclass, 0, newname));
318
addRRset(name, response, rrset, Section.ANSWER, flags);
319
if (zone != null && iterations == 0)
320
response.getHeader().setFlag(Flags.AA);
321
rcode = addAnswer(response, newname, type, dclass,
322
iterations + 1, flags);
325
else if (sr.isSuccessful()) {
326
RRset [] rrsets = sr.answers();
328
for (int i = 0; i < rrsets.length; i++)
329
addRRset(name, response, rrsets[i],
330
Section.ANSWER, flags);
333
addNS(response, zone, flags);
335
response.getHeader().setFlag(Flags.AA);
338
addCacheNS(response, getCache(dclass), name);
345
addSOA(Message response, Zone zone) {
346
response.addRecord(zone.getSOA(), Section.AUTHORITY);
350
addNS(Message response, Zone zone, int flags) {
351
RRset nsRecords = zone.getNS();
352
addRRset(nsRecords.getName(), response, nsRecords,
353
Section.AUTHORITY, flags);
357
addCacheNS(Message response, Cache cache, Name name) {
358
SetResponse sr = cache.lookupRecords(name, Type.NS, Credibility.HINT);
359
if (!sr.isDelegation())
361
RRset nsRecords = sr.getNS();
362
Iterator it = nsRecords.rrs();
363
while (it.hasNext()) {
364
Record r = (Record) it.next();
365
response.addRecord(r, Section.AUTHORITY);
371
doAXFR(Name name, Message query, TSIG tsig, TSIGRecord qtsig, Socket s) {
372
Zone zone = (Zone) ZoneManager.getZone(name);
373
boolean first = true;
375
return errorMessage(query, Rcode.REFUSED);
376
Iterator it = zone.AXFR();
378
DataOutputStream dataOut;
379
dataOut = new DataOutputStream(s.getOutputStream());
380
int id = query.getHeader().getID();
381
while (it.hasNext()) {
382
RRset rrset = (RRset) it.next();
383
Message response = new Message(id);
384
Header header = response.getHeader();
385
header.setFlag(Flags.QR);
386
header.setFlag(Flags.AA);
387
addRRset(rrset.getName(), response, rrset,
388
Section.ANSWER, FLAG_DNSSECOK);
390
tsig.applyStream(response, qtsig, first);
391
qtsig = response.getTSIG();
394
byte [] out = response.toWire();
395
dataOut.writeShort(out.length);
399
catch (IOException ex) {
400
System.out.println("AXFR failed");
405
catch (IOException ex) {
411
addRRset(Name name, Message response, RRset rrset, int section, int flags) {
412
for (int s = 1; s <= section; s++)
413
if (response.findRRset(name, rrset.getType(), s))
415
if ((flags & FLAG_SIGONLY) == 0) {
416
Iterator it = rrset.rrs();
417
while (it.hasNext()) {
418
Record r = (Record) it.next();
419
if (r.getName().isWild() && !name.isWild())
420
r = r.withName(name);
421
response.addRecord(r, section);
424
if ((flags & (FLAG_SIGONLY | FLAG_DNSSECOK)) != 0) {
425
Iterator it = rrset.sigs();
426
while (it.hasNext()) {
427
Record r = (Record) it.next();
428
if (r.getName().isWild() && !name.isWild())
429
r = r.withName(name);
430
response.addRecord(r, section);
436
buildErrorMessage(Header header, int rcode, Record question) {
437
Message response = new Message();
438
response.setHeader(header);
439
for (int i = 0; i < 4; i++)
440
response.removeAllRecords(i);
441
if (rcode == Rcode.SERVFAIL)
442
response.addRecord(question, Section.QUESTION);
443
header.setRcode(rcode);
444
return response.toWire();
448
errorMessage(Message query, int rcode) {
449
return buildErrorMessage(query.getHeader(), rcode,
450
query.getQuestion());
454
formerrMessage(byte [] in) {
457
header = new Header(in);
459
catch (IOException e) {
462
return buildErrorMessage(header, Rcode.FORMERR, null);
466
getCache(int dclass) {
467
Cache c = (Cache) caches.get(new Integer(dclass));
469
c = new Cache(dclass);
470
caches.put(new Integer(dclass), c);