Source Code Cross Referenced for ZoneTransferIn.java in  » Net » dnsjava » org » xbill » DNS » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » dnsjava » org.xbill.DNS 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org)
002:        // Parts of this are derived from lib/dns/xfrin.c from BIND 9; its copyright
003:        // notice follows.
004:
005:        /*
006:         * Copyright (C) 1999-2001  Internet Software Consortium.
007:         *
008:         * Permission to use, copy, modify, and distribute this software for any
009:         * purpose with or without fee is hereby granted, provided that the above
010:         * copyright notice and this permission notice appear in all copies.
011:         *
012:         * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
013:         * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
014:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
015:         * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
016:         * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
017:         * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
018:         * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
019:         * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
020:         */
021:
022:        package org.xbill.DNS;
023:
024:        import java.io.*;
025:        import java.net.*;
026:        import java.util.*;
027:
028:        /**
029:         * An incoming DNS Zone Transfer.  To use this class, first initialize an
030:         * object, then call the run() method.  If run() doesn't throw an exception
031:         * the result will either be an IXFR-style response, an AXFR-style response,
032:         * or an indication that the zone is up to date.
033:         *
034:         * @author Brian Wellington
035:         */
036:
037:        public class ZoneTransferIn {
038:
039:            private static final int INITIALSOA = 0;
040:            private static final int FIRSTDATA = 1;
041:            private static final int IXFR_DELSOA = 2;
042:            private static final int IXFR_DEL = 3;
043:            private static final int IXFR_ADDSOA = 4;
044:            private static final int IXFR_ADD = 5;
045:            private static final int AXFR = 6;
046:            private static final int END = 7;
047:
048:            private Name zname;
049:            private int qtype;
050:            private int dclass;
051:            private long ixfr_serial;
052:            private boolean want_fallback;
053:
054:            private SocketAddress localAddress;
055:            private SocketAddress address;
056:            private TCPClient client;
057:            private TSIG tsig;
058:            private TSIG.StreamVerifier verifier;
059:            private long timeout = 900 * 1000;
060:
061:            private int state;
062:            private long end_serial;
063:            private long current_serial;
064:            private Record initialsoa;
065:
066:            private int rtype;
067:
068:            private List axfr;
069:            private List ixfr;
070:
071:            public static class Delta {
072:                /**
073:                 * All changes between two versions of a zone in an IXFR response.
074:                 */
075:
076:                /** The starting serial number of this delta. */
077:                public long start;
078:
079:                /** The ending serial number of this delta. */
080:                public long end;
081:
082:                /** A list of records added between the start and end versions */
083:                public List adds;
084:
085:                /** A list of records deleted between the start and end versions */
086:                public List deletes;
087:
088:                private Delta() {
089:                    adds = new ArrayList();
090:                    deletes = new ArrayList();
091:                }
092:            }
093:
094:            private ZoneTransferIn() {
095:            }
096:
097:            private ZoneTransferIn(Name zone, int xfrtype, long serial,
098:                    boolean fallback, SocketAddress address, TSIG key) {
099:                this .address = address;
100:                this .tsig = key;
101:                if (zone.isAbsolute())
102:                    zname = zone;
103:                else {
104:                    try {
105:                        zname = Name.concatenate(zone, Name.root);
106:                    } catch (NameTooLongException e) {
107:                        throw new IllegalArgumentException("ZoneTransferIn: "
108:                                + "name too long");
109:                    }
110:                }
111:                qtype = xfrtype;
112:                dclass = DClass.IN;
113:                ixfr_serial = serial;
114:                want_fallback = fallback;
115:                state = INITIALSOA;
116:            }
117:
118:            /**
119:             * Instantiates a ZoneTransferIn object to do an AXFR (full zone transfer).
120:             * @param zone The zone to transfer.
121:             * @param address The host/port from which to transfer the zone.
122:             * @param key The TSIG key used to authenticate the transfer, or null.
123:             * @return The ZoneTransferIn object.
124:             * @throws UnknownHostException The host does not exist.
125:             */
126:            public static ZoneTransferIn newAXFR(Name zone,
127:                    SocketAddress address, TSIG key) {
128:                return new ZoneTransferIn(zone, Type.AXFR, 0, false, address,
129:                        key);
130:            }
131:
132:            /**
133:             * Instantiates a ZoneTransferIn object to do an AXFR (full zone transfer).
134:             * @param zone The zone to transfer.
135:             * @param host The host from which to transfer the zone.
136:             * @param port The port to connect to on the server, or 0 for the default.
137:             * @param key The TSIG key used to authenticate the transfer, or null.
138:             * @return The ZoneTransferIn object.
139:             * @throws UnknownHostException The host does not exist.
140:             */
141:            public static ZoneTransferIn newAXFR(Name zone, String host,
142:                    int port, TSIG key) throws UnknownHostException {
143:                if (port == 0)
144:                    port = SimpleResolver.DEFAULT_PORT;
145:                return newAXFR(zone, new InetSocketAddress(host, port), key);
146:            }
147:
148:            /**
149:             * Instantiates a ZoneTransferIn object to do an AXFR (full zone transfer).
150:             * @param zone The zone to transfer.
151:             * @param host The host from which to transfer the zone.
152:             * @param key The TSIG key used to authenticate the transfer, or null.
153:             * @return The ZoneTransferIn object.
154:             * @throws UnknownHostException The host does not exist.
155:             */
156:            public static ZoneTransferIn newAXFR(Name zone, String host,
157:                    TSIG key) throws UnknownHostException {
158:                return newAXFR(zone, host, 0, key);
159:            }
160:
161:            /**
162:             * Instantiates a ZoneTransferIn object to do an IXFR (incremental zone
163:             * transfer).
164:             * @param zone The zone to transfer.
165:             * @param serial The existing serial number.
166:             * @param fallback If true, fall back to AXFR if IXFR is not supported.
167:             * @param address The host/port from which to transfer the zone.
168:             * @param key The TSIG key used to authenticate the transfer, or null.
169:             * @return The ZoneTransferIn object.
170:             * @throws UnknownHostException The host does not exist.
171:             */
172:            public static ZoneTransferIn newIXFR(Name zone, long serial,
173:                    boolean fallback, SocketAddress address, TSIG key) {
174:                return new ZoneTransferIn(zone, Type.IXFR, serial, fallback,
175:                        address, key);
176:            }
177:
178:            /**
179:             * Instantiates a ZoneTransferIn object to do an IXFR (incremental zone
180:             * transfer).
181:             * @param zone The zone to transfer.
182:             * @param serial The existing serial number.
183:             * @param fallback If true, fall back to AXFR if IXFR is not supported.
184:             * @param host The host from which to transfer the zone.
185:             * @param port The port to connect to on the server, or 0 for the default.
186:             * @param key The TSIG key used to authenticate the transfer, or null.
187:             * @return The ZoneTransferIn object.
188:             * @throws UnknownHostException The host does not exist.
189:             */
190:            public static ZoneTransferIn newIXFR(Name zone, long serial,
191:                    boolean fallback, String host, int port, TSIG key)
192:                    throws UnknownHostException {
193:                if (port == 0)
194:                    port = SimpleResolver.DEFAULT_PORT;
195:                return newIXFR(zone, serial, fallback, new InetSocketAddress(
196:                        host, port), key);
197:            }
198:
199:            /**
200:             * Instantiates a ZoneTransferIn object to do an IXFR (incremental zone
201:             * transfer).
202:             * @param zone The zone to transfer.
203:             * @param serial The existing serial number.
204:             * @param fallback If true, fall back to AXFR if IXFR is not supported.
205:             * @param host The host from which to transfer the zone.
206:             * @param key The TSIG key used to authenticate the transfer, or null.
207:             * @return The ZoneTransferIn object.
208:             * @throws UnknownHostException The host does not exist.
209:             */
210:            public static ZoneTransferIn newIXFR(Name zone, long serial,
211:                    boolean fallback, String host, TSIG key)
212:                    throws UnknownHostException {
213:                return newIXFR(zone, serial, fallback, host, 0, key);
214:            }
215:
216:            /**
217:             * Gets the name of the zone being transferred.
218:             */
219:            public Name getName() {
220:                return zname;
221:            }
222:
223:            /**
224:             * Gets the type of zone transfer (either AXFR or IXFR).
225:             */
226:            public int getType() {
227:                return qtype;
228:            }
229:
230:            /**
231:             * Sets a timeout on this zone transfer.  The default is 900 seconds (15
232:             * minutes).
233:             * @param secs The maximum amount of time that this zone transfer can take.
234:             */
235:            public void setTimeout(int secs) {
236:                if (secs < 0)
237:                    throw new IllegalArgumentException("timeout cannot be "
238:                            + "negative");
239:                timeout = 1000L * secs;
240:            }
241:
242:            /**
243:             * Sets an alternate DNS class for this zone transfer.
244:             * @param dclass The class to use instead of class IN.
245:             */
246:            public void setDClass(int dclass) {
247:                DClass.check(dclass);
248:                this .dclass = dclass;
249:            }
250:
251:            /**
252:             * Sets the local address to bind to when sending messages.
253:             * @param addr The local address to send messages from.
254:             */
255:            public void setLocalAddress(SocketAddress addr) {
256:                this .localAddress = addr;
257:            }
258:
259:            private void openConnection() throws IOException {
260:                long endTime = System.currentTimeMillis() + timeout;
261:                client = new TCPClient(endTime);
262:                if (localAddress != null)
263:                    client.bind(localAddress);
264:                client.connect(address);
265:            }
266:
267:            private void sendQuery() throws IOException {
268:                Record question = Record.newRecord(zname, qtype, dclass);
269:
270:                Message query = new Message();
271:                query.getHeader().setOpcode(Opcode.QUERY);
272:                query.addRecord(question, Section.QUESTION);
273:                if (qtype == Type.IXFR) {
274:                    Record soa = new SOARecord(zname, dclass, 0, Name.root,
275:                            Name.root, ixfr_serial, 0, 0, 0, 0);
276:                    query.addRecord(soa, Section.AUTHORITY);
277:                }
278:                if (tsig != null) {
279:                    tsig.apply(query, null);
280:                    verifier = new TSIG.StreamVerifier(tsig, query.getTSIG());
281:                }
282:                byte[] out = query.toWire(Message.MAXLENGTH);
283:                client.send(out);
284:            }
285:
286:            private long getSOASerial(Record rec) {
287:                SOARecord soa = (SOARecord) rec;
288:                return soa.getSerial();
289:            }
290:
291:            private void logxfr(String s) {
292:                if (Options.check("verbose"))
293:                    System.out.println(zname + ": " + s);
294:            }
295:
296:            private void fail(String s) throws ZoneTransferException {
297:                throw new ZoneTransferException(s);
298:            }
299:
300:            private void fallback() throws ZoneTransferException {
301:                if (!want_fallback)
302:                    fail("server doesn't support IXFR");
303:
304:                logxfr("falling back to AXFR");
305:                qtype = Type.AXFR;
306:                state = INITIALSOA;
307:            }
308:
309:            private void parseRR(Record rec) throws ZoneTransferException {
310:                Name name = rec.getName();
311:                int type = rec.getType();
312:                Delta delta;
313:
314:                switch (state) {
315:                case INITIALSOA:
316:                    if (type != Type.SOA)
317:                        fail("missing initial SOA");
318:                    initialsoa = rec;
319:                    // Remember the serial number in the initial SOA; we need it
320:                    // to recognize the end of an IXFR.
321:                    end_serial = getSOASerial(rec);
322:                    if (qtype == Type.IXFR && end_serial <= ixfr_serial) {
323:                        logxfr("up to date");
324:                        state = END;
325:                        break;
326:                    }
327:                    state = FIRSTDATA;
328:                    break;
329:
330:                case FIRSTDATA:
331:                    // If the transfer begins with 1 SOA, it's an AXFR.
332:                    // If it begins with 2 SOAs, it's an IXFR.
333:                    if (qtype == Type.IXFR && type == Type.SOA
334:                            && getSOASerial(rec) == ixfr_serial) {
335:                        rtype = Type.IXFR;
336:                        ixfr = new ArrayList();
337:                        logxfr("got incremental response");
338:                        state = IXFR_DELSOA;
339:                    } else {
340:                        rtype = Type.AXFR;
341:                        axfr = new ArrayList();
342:                        axfr.add(initialsoa);
343:                        logxfr("got nonincremental response");
344:                        state = AXFR;
345:                    }
346:                    parseRR(rec); // Restart...
347:                    return;
348:
349:                case IXFR_DELSOA:
350:                    delta = new Delta();
351:                    ixfr.add(delta);
352:                    delta.start = getSOASerial(rec);
353:                    delta.deletes.add(rec);
354:                    state = IXFR_DEL;
355:                    break;
356:
357:                case IXFR_DEL:
358:                    if (type == Type.SOA) {
359:                        current_serial = getSOASerial(rec);
360:                        state = IXFR_ADDSOA;
361:                        parseRR(rec); // Restart...
362:                        return;
363:                    }
364:                    delta = (Delta) ixfr.get(ixfr.size() - 1);
365:                    delta.deletes.add(rec);
366:                    break;
367:
368:                case IXFR_ADDSOA:
369:                    delta = (Delta) ixfr.get(ixfr.size() - 1);
370:                    delta.end = getSOASerial(rec);
371:                    delta.adds.add(rec);
372:                    state = IXFR_ADD;
373:                    break;
374:
375:                case IXFR_ADD:
376:                    if (type == Type.SOA) {
377:                        long soa_serial = getSOASerial(rec);
378:                        if (soa_serial == end_serial) {
379:                            state = END;
380:                            break;
381:                        } else if (soa_serial != current_serial) {
382:                            fail("IXFR out of sync: expected serial "
383:                                    + current_serial + " , got " + soa_serial);
384:                        } else {
385:                            state = IXFR_DELSOA;
386:                            parseRR(rec); // Restart...
387:                            return;
388:                        }
389:                    }
390:                    delta = (Delta) ixfr.get(ixfr.size() - 1);
391:                    delta.adds.add(rec);
392:                    break;
393:
394:                case AXFR:
395:                    // Old BINDs sent cross class A records for non IN classes.
396:                    if (type == Type.A && rec.getDClass() != dclass)
397:                        break;
398:                    axfr.add(rec);
399:                    if (type == Type.SOA) {
400:                        state = END;
401:                    }
402:                    break;
403:
404:                case END:
405:                    fail("extra data");
406:                    break;
407:
408:                default:
409:                    fail("invalid state");
410:                    break;
411:                }
412:            }
413:
414:            private void closeConnection() {
415:                try {
416:                    if (client != null)
417:                        client.cleanup();
418:                } catch (IOException e) {
419:                }
420:            }
421:
422:            private Message parseMessage(byte[] b) throws WireParseException {
423:                try {
424:                    return new Message(b);
425:                } catch (IOException e) {
426:                    if (e instanceof  WireParseException)
427:                        throw (WireParseException) e;
428:                    throw new WireParseException("Error parsing message");
429:                }
430:            }
431:
432:            private void doxfr() throws IOException, ZoneTransferException {
433:                sendQuery();
434:                while (state != END) {
435:                    byte[] in = client.recv();
436:                    Message response = parseMessage(in);
437:                    if (response.getHeader().getRcode() == Rcode.NOERROR
438:                            && verifier != null) {
439:                        TSIGRecord tsigrec = response.getTSIG();
440:
441:                        int error = verifier.verify(response, in);
442:                        if (error == Rcode.NOERROR && tsigrec != null)
443:                            response.tsigState = Message.TSIG_VERIFIED;
444:                        else if (error == Rcode.NOERROR)
445:                            response.tsigState = Message.TSIG_INTERMEDIATE;
446:                        else
447:                            fail("TSIG failure");
448:                    }
449:
450:                    Record[] answers = response.getSectionArray(Section.ANSWER);
451:
452:                    if (state == INITIALSOA) {
453:                        int rcode = response.getRcode();
454:                        if (rcode != Rcode.NOERROR) {
455:                            if (qtype == Type.IXFR && rcode == Rcode.NOTIMP) {
456:                                fallback();
457:                                doxfr();
458:                                return;
459:                            }
460:                            fail(Rcode.string(rcode));
461:                        }
462:
463:                        Record question = response.getQuestion();
464:                        if (question != null && question.getType() != qtype) {
465:                            fail("invalid question section");
466:                        }
467:
468:                        if (answers.length == 0 && qtype == Type.IXFR) {
469:                            fallback();
470:                            doxfr();
471:                            return;
472:                        }
473:                    }
474:
475:                    for (int i = 0; i < answers.length; i++) {
476:                        parseRR(answers[i]);
477:                    }
478:
479:                    if (state == END
480:                            && response.tsigState == Message.TSIG_INTERMEDIATE)
481:                        fail("last message must be signed");
482:                }
483:            }
484:
485:            /**
486:             * Does the zone transfer.
487:             * @return A list, which is either an AXFR-style response (List of Records),
488:             * and IXFR-style response (List of Deltas), or null, which indicates that
489:             * an IXFR was performed and the zone is up to date.
490:             * @throws IOException The zone transfer failed to due an IO problem.
491:             * @throws ZoneTransferException The zone transfer failed to due a problem
492:             * with the zone transfer itself.
493:             */
494:            public List run() throws IOException, ZoneTransferException {
495:                try {
496:                    openConnection();
497:                    doxfr();
498:                } finally {
499:                    closeConnection();
500:                }
501:                if (axfr != null)
502:                    return axfr;
503:                return ixfr;
504:            }
505:
506:            /**
507:             * Returns true if the response is an AXFR-style response (List of Records).
508:             * This will be true if either an IXFR was performed, an IXFR was performed
509:             * and the server provided a full zone transfer, or an IXFR failed and
510:             * fallback to AXFR occurred.
511:             */
512:            public boolean isAXFR() {
513:                return (rtype == Type.AXFR);
514:            }
515:
516:            /**
517:             * Gets the AXFR-style response.
518:             */
519:            public List getAXFR() {
520:                return axfr;
521:            }
522:
523:            /**
524:             * Returns true if the response is an IXFR-style response (List of Deltas).
525:             * This will be true only if an IXFR was performed and the server provided
526:             * an incremental zone transfer.
527:             */
528:            public boolean isIXFR() {
529:                return (rtype == Type.IXFR);
530:            }
531:
532:            /**
533:             * Gets the IXFR-style response.
534:             */
535:            public List getIXFR() {
536:                return ixfr;
537:            }
538:
539:            /**
540:             * Returns true if the response indicates that the zone is up to date.
541:             * This will be true only if an IXFR was performed.
542:             */
543:            public boolean isCurrent() {
544:                return (axfr == null && ixfr == null);
545:            }
546:
547:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.