Source Code Cross Referenced for ResourceRecord.java in  » 6.0-JDK-Modules-com.sun » jndi » com » sun » jndi » 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 » 6.0 JDK Modules com.sun » jndi » com.sun.jndi.dns 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2000-2002 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package com.sun.jndi.dns;
027:
028:        import javax.naming.InvalidNameException;
029:
030:        /**
031:         * The ResourceRecord class represents a DNS resource record.
032:         * The string format is based on the master file representation in
033:         * RFC 1035.
034:         *
035:         * @author Scott Seligman
036:         * @version 1.22 07/05/05
037:         */
038:
039:        public class ResourceRecord {
040:
041:            /*
042:             * Resource record type codes
043:             */
044:            static final int TYPE_A = 1;
045:            static final int TYPE_NS = 2;
046:            static final int TYPE_CNAME = 5;
047:            static final int TYPE_SOA = 6;
048:            static final int TYPE_PTR = 12;
049:            static final int TYPE_HINFO = 13;
050:            static final int TYPE_MX = 15;
051:            static final int TYPE_TXT = 16;
052:            static final int TYPE_AAAA = 28;
053:            static final int TYPE_SRV = 33;
054:            static final int TYPE_NAPTR = 35;
055:            static final int QTYPE_AXFR = 252; // zone transfer
056:            static final int QTYPE_STAR = 255; // query type "*"
057:
058:            /*
059:             * Mapping from resource record type codes to type name strings.
060:             */
061:            static final String rrTypeNames[] = { null, "A", "NS", null, null,
062:                    "CNAME", "SOA", null, null, null, null, null, "PTR",
063:                    "HINFO", null, "MX", "TXT", null, null, null, null, null,
064:                    null, null, null, null, null, null, "AAAA", null, null,
065:                    null, null, "SRV", null, "NAPTR" };
066:
067:            /*
068:             * Resource record class codes
069:             */
070:            static final int CLASS_INTERNET = 1;
071:            static final int CLASS_HESIOD = 2;
072:            static final int QCLASS_STAR = 255; // query class "*"
073:
074:            /*
075:             * Mapping from resource record type codes to class name strings.
076:             */
077:            static final String rrClassNames[] = { null, "IN", null, null, "HS" };
078:
079:            byte[] msg; // DNS message
080:            int msgLen; // msg size (in octets)
081:            boolean qSection; // true if this RR is part of question section
082:            // and therefore has no ttl or rdata
083:            int offset; // offset of RR w/in msg
084:            int rrlen; // number of octets in encoded RR
085:            DnsName name; // name field of RR, including root label
086:            int rrtype; // type field of RR
087:            String rrtypeName; // name of of rrtype
088:            int rrclass; // class field of RR
089:            String rrclassName; // name of rrclass
090:            int ttl = 0; // ttl field of RR
091:            int rdlen = 0; // number of octets of rdata
092:            Object rdata = null; // rdata -- most are String, unknown are byte[]
093:
094:            /*
095:             * Constructs a new ResourceRecord.  The encoded data of the DNS
096:             * message is contained in msg; data for this RR begins at msg[offset].
097:             * If qSection is true this RR is part of a question section.  It's
098:             * not a true resource record in that case, but is treated as if it
099:             * were a shortened one (with no ttl or rdata).  If decodeRdata is
100:             * false, the rdata is not decoded (and getRdata() will return null)
101:             * unless this is an SOA record.
102:             *
103:             * @throws InvalidNameException if a decoded domain name isn't valid.
104:             * @throws ArrayIndexOutOfBoundsException given certain other corrupt data.
105:             */
106:            ResourceRecord(byte[] msg, int msgLen, int offset,
107:                    boolean qSection, boolean decodeRdata)
108:                    throws InvalidNameException {
109:
110:                this .msg = msg;
111:                this .msgLen = msgLen;
112:                this .offset = offset;
113:                this .qSection = qSection;
114:                decode(decodeRdata);
115:            }
116:
117:            public String toString() {
118:                String text = name + " " + rrclassName + " " + rrtypeName;
119:                if (!qSection) {
120:                    text += " " + ttl + " "
121:                            + ((rdata != null) ? rdata : "[n/a]");
122:                }
123:                return text;
124:            }
125:
126:            /*
127:             * Returns the name field of this RR, including the root label.
128:             */
129:            public DnsName getName() {
130:                return name;
131:            }
132:
133:            /*
134:             * Returns the number of octets in the encoded RR.
135:             */
136:            public int size() {
137:                return rrlen;
138:            }
139:
140:            public int getType() {
141:                return rrtype;
142:            }
143:
144:            public int getRrclass() {
145:                return rrclass;
146:            }
147:
148:            public Object getRdata() {
149:                return rdata;
150:            }
151:
152:            public static String getTypeName(int rrtype) {
153:                return valueToName(rrtype, rrTypeNames);
154:            }
155:
156:            public static int getType(String typeName) {
157:                return nameToValue(typeName, rrTypeNames);
158:            }
159:
160:            public static String getRrclassName(int rrclass) {
161:                return valueToName(rrclass, rrClassNames);
162:            }
163:
164:            public static int getRrclass(String className) {
165:                return nameToValue(className, rrClassNames);
166:            }
167:
168:            private static String valueToName(int val, String[] names) {
169:                String name = null;
170:                if ((val > 0) && (val < names.length)) {
171:                    name = names[val];
172:                } else if (val == QTYPE_STAR) { // QTYPE_STAR == QCLASS_STAR
173:                    name = "*";
174:                }
175:                if (name == null) {
176:                    name = Integer.toString(val);
177:                }
178:                return name;
179:            }
180:
181:            private static int nameToValue(String name, String[] names) {
182:                if (name.equals("")) {
183:                    return -1; // invalid name
184:                } else if (name.equals("*")) {
185:                    return QTYPE_STAR; // QTYPE_STAR == QCLASS_STAR
186:                }
187:                if (Character.isDigit(name.charAt(0))) {
188:                    try {
189:                        return Integer.parseInt(name);
190:                    } catch (NumberFormatException e) {
191:                    }
192:                }
193:                for (int i = 1; i < names.length; i++) {
194:                    if ((names[i] != null) && name.equalsIgnoreCase(names[i])) {
195:                        return i;
196:                    }
197:                }
198:                return -1; // unknown name
199:            }
200:
201:            /*
202:             * Compares two SOA record serial numbers using 32-bit serial number
203:             * arithmetic as defined in RFC 1982.  Serial numbers are unsigned
204:             * 32-bit quantities.  Returns a negative, zero, or positive value
205:             * as the first serial number is less than, equal to, or greater
206:             * than the second.  If the serial numbers are not comparable the
207:             * result is undefined.  Note that the relation is not transitive.
208:             */
209:            public static int compareSerialNumbers(long s1, long s2) {
210:                long diff = s2 - s1;
211:                if (diff == 0) {
212:                    return 0;
213:                } else if ((diff > 0 && diff <= 0x7FFFFFFF)
214:                        || (diff < 0 && -diff > 0x7FFFFFFF)) {
215:                    return -1;
216:                } else {
217:                    return 1;
218:                }
219:            }
220:
221:            /*
222:             * Decodes the binary format of the RR.
223:             * May throw ArrayIndexOutOfBoundsException given corrupt data.
224:             */
225:            private void decode(boolean decodeRdata)
226:                    throws InvalidNameException {
227:                int pos = offset; // index of next unread octet
228:
229:                name = new DnsName(); // NAME
230:                pos = decodeName(pos, name);
231:
232:                rrtype = getUShort(pos); // TYPE
233:                rrtypeName = (rrtype < rrTypeNames.length) ? rrTypeNames[rrtype]
234:                        : null;
235:                if (rrtypeName == null) {
236:                    rrtypeName = Integer.toString(rrtype);
237:                }
238:                pos += 2;
239:
240:                rrclass = getUShort(pos); // CLASS
241:                rrclassName = (rrclass < rrClassNames.length) ? rrClassNames[rrclass]
242:                        : null;
243:                if (rrclassName == null) {
244:                    rrclassName = Integer.toString(rrclass);
245:                }
246:                pos += 2;
247:
248:                if (!qSection) {
249:                    ttl = getInt(pos); // TTL
250:                    pos += 4;
251:
252:                    rdlen = getUShort(pos); // RDLENGTH
253:                    pos += 2;
254:
255:                    rdata = (decodeRdata || // RDATA
256:                    (rrtype == TYPE_SOA)) ? decodeRdata(pos) : null;
257:                    if (rdata instanceof  DnsName) {
258:                        rdata = rdata.toString();
259:                    }
260:                    pos += rdlen;
261:                }
262:
263:                rrlen = pos - offset;
264:
265:                msg = null; // free up for GC
266:            }
267:
268:            /*
269:             * Returns the 1-byte unsigned value at msg[pos].
270:             */
271:            private int getUByte(int pos) {
272:                return (msg[pos] & 0xFF);
273:            }
274:
275:            /*
276:             * Returns the 2-byte unsigned value at msg[pos].  The high
277:             * order byte comes first.
278:             */
279:            private int getUShort(int pos) {
280:                return (((msg[pos] & 0xFF) << 8) | (msg[pos + 1] & 0xFF));
281:            }
282:
283:            /*
284:             * Returns the 4-byte signed value at msg[pos].  The high
285:             * order byte comes first.
286:             */
287:            private int getInt(int pos) {
288:                return ((getUShort(pos) << 16) | getUShort(pos + 2));
289:            }
290:
291:            /*
292:             * Returns the 4-byte unsigned value at msg[pos].  The high
293:             * order byte comes first.
294:             */
295:            private long getUInt(int pos) {
296:                return (getInt(pos) & 0xffffffffL);
297:            }
298:
299:            /*
300:             * Returns the name encoded at msg[pos], including the root label.
301:             */
302:            private DnsName decodeName(int pos) throws InvalidNameException {
303:                DnsName n = new DnsName();
304:                decodeName(pos, n);
305:                return n;
306:            }
307:
308:            /*
309:             * Prepends to "n" the domain name encoded at msg[pos], including the root
310:             * label.  Returns the index into "msg" following the name.
311:             */
312:            private int decodeName(int pos, DnsName n)
313:                    throws InvalidNameException {
314:                if (msg[pos] == 0) { // end of name
315:                    n.add(0, "");
316:                    return (pos + 1);
317:                } else if ((msg[pos] & 0xC0) != 0) { // name compression
318:                    decodeName(getUShort(pos) & 0x3FFF, n);
319:                    return (pos + 2);
320:                } else { // append a label
321:                    int len = msg[pos++];
322:                    try {
323:                        n.add(0, new String(msg, pos, len, "ISO-8859-1"));
324:                    } catch (java.io.UnsupportedEncodingException e) {
325:                        // assert false : "ISO-Latin-1 charset unavailable";
326:                    }
327:                    return decodeName(pos + len, n);
328:                }
329:            }
330:
331:            /*
332:             * Returns the rdata encoded at msg[pos].  The format is dependent
333:             * on the rrtype and rrclass values, which have already been set.
334:             * The length of the encoded data is rdlen, which has already been
335:             * set.
336:             * The rdata of records with unknown type/class combinations is
337:             * returned in a newly-allocated byte array.
338:             */
339:            private Object decodeRdata(int pos) throws InvalidNameException {
340:                if (rrclass == CLASS_INTERNET) {
341:                    switch (rrtype) {
342:                    case TYPE_A:
343:                        return decodeA(pos);
344:                    case TYPE_AAAA:
345:                        return decodeAAAA(pos);
346:                    case TYPE_CNAME:
347:                    case TYPE_NS:
348:                    case TYPE_PTR:
349:                        return decodeName(pos);
350:                    case TYPE_MX:
351:                        return decodeMx(pos);
352:                    case TYPE_SOA:
353:                        return decodeSoa(pos);
354:                    case TYPE_SRV:
355:                        return decodeSrv(pos);
356:                    case TYPE_NAPTR:
357:                        return decodeNaptr(pos);
358:                    case TYPE_TXT:
359:                        return decodeTxt(pos);
360:                    case TYPE_HINFO:
361:                        return decodeHinfo(pos);
362:                    }
363:                }
364:                // Unknown RR type/class
365:                byte[] rd = new byte[rdlen];
366:                System.arraycopy(msg, pos, rd, 0, rdlen);
367:                return rd;
368:            }
369:
370:            /*
371:             * Returns the rdata of an MX record that is encoded at msg[pos].
372:             */
373:            private String decodeMx(int pos) throws InvalidNameException {
374:                int preference = getUShort(pos);
375:                pos += 2;
376:                DnsName name = decodeName(pos);
377:                return (preference + " " + name);
378:            }
379:
380:            /*
381:             * Returns the rdata of an SOA record that is encoded at msg[pos].
382:             */
383:            private String decodeSoa(int pos) throws InvalidNameException {
384:                DnsName mname = new DnsName();
385:                pos = decodeName(pos, mname);
386:                DnsName rname = new DnsName();
387:                pos = decodeName(pos, rname);
388:
389:                long serial = getUInt(pos);
390:                pos += 4;
391:                long refresh = getUInt(pos);
392:                pos += 4;
393:                long retry = getUInt(pos);
394:                pos += 4;
395:                long expire = getUInt(pos);
396:                pos += 4;
397:                long minimum = getUInt(pos); // now used as negative TTL
398:                pos += 4;
399:
400:                return (mname + " " + rname + " " + serial + " " + refresh
401:                        + " " + retry + " " + expire + " " + minimum);
402:            }
403:
404:            /*
405:             * Returns the rdata of an SRV record that is encoded at msg[pos].
406:             * See RFC 2782.
407:             */
408:            private String decodeSrv(int pos) throws InvalidNameException {
409:                int priority = getUShort(pos);
410:                pos += 2;
411:                int weight = getUShort(pos);
412:                pos += 2;
413:                int port = getUShort(pos);
414:                pos += 2;
415:                DnsName target = decodeName(pos);
416:                return (priority + " " + weight + " " + port + " " + target);
417:            }
418:
419:            /*
420:             * Returns the rdata of an NAPTR record that is encoded at msg[pos].
421:             * See RFC 2915.
422:             */
423:            private String decodeNaptr(int pos) throws InvalidNameException {
424:                int order = getUShort(pos);
425:                pos += 2;
426:                int preference = getUShort(pos);
427:                pos += 2;
428:                StringBuffer flags = new StringBuffer();
429:                pos += decodeCharString(pos, flags);
430:                StringBuffer services = new StringBuffer();
431:                pos += decodeCharString(pos, services);
432:                StringBuffer regexp = new StringBuffer(rdlen);
433:                pos += decodeCharString(pos, regexp);
434:                DnsName replacement = decodeName(pos);
435:
436:                return (order + " " + preference + " " + flags + " " + services
437:                        + " " + regexp + " " + replacement);
438:            }
439:
440:            /*
441:             * Returns the rdata of a TXT record that is encoded at msg[pos].
442:             * The rdata consists of one or more <character-string>s.
443:             */
444:            private String decodeTxt(int pos) {
445:                StringBuffer buf = new StringBuffer(rdlen);
446:                int end = pos + rdlen;
447:                while (pos < end) {
448:                    pos += decodeCharString(pos, buf);
449:                    if (pos < end) {
450:                        buf.append(' ');
451:                    }
452:                }
453:                return buf.toString();
454:            }
455:
456:            /*
457:             * Returns the rdata of an HINFO record that is encoded at msg[pos].
458:             * The rdata consists of two <character-string>s.
459:             */
460:            private String decodeHinfo(int pos) {
461:                StringBuffer buf = new StringBuffer(rdlen);
462:                pos += decodeCharString(pos, buf);
463:                buf.append(' ');
464:                pos += decodeCharString(pos, buf);
465:                return buf.toString();
466:            }
467:
468:            /*
469:             * Decodes the <character-string> at msg[pos] and adds it to buf.
470:             * If the string contains one of the meta-characters ' ', '\\', or
471:             * '"', then the result is quoted and any embedded '\\' or '"'
472:             * chars are escaped with '\\'.  Empty strings are also quoted.
473:             * Returns the size of the encoded string, including the initial
474:             * length octet.
475:             */
476:            private int decodeCharString(int pos, StringBuffer buf) {
477:                int start = buf.length(); // starting index of this string
478:                int len = getUByte(pos++); // encoded string length
479:                boolean quoted = (len == 0); // quote string if empty
480:                for (int i = 0; i < len; i++) {
481:                    int c = getUByte(pos++);
482:                    quoted |= (c == ' ');
483:                    if ((c == '\\') || (c == '"')) {
484:                        quoted = true;
485:                        buf.append('\\');
486:                    }
487:                    buf.append((char) c);
488:                }
489:                if (quoted) {
490:                    buf.insert(start, '"');
491:                    buf.append('"');
492:                }
493:                return (len + 1); // size includes initial octet
494:            }
495:
496:            /*
497:             * Returns the rdata of an A record, in dotted-decimal format,
498:             * that is encoded at msg[pos].
499:             */
500:            private String decodeA(int pos) {
501:                return ((msg[pos] & 0xff) + "." + (msg[pos + 1] & 0xff) + "."
502:                        + (msg[pos + 2] & 0xff) + "." + (msg[pos + 3] & 0xff));
503:            }
504:
505:            /*
506:             * Returns the rdata of an AAAA record, in colon-separated format,
507:             * that is encoded at msg[pos].  For example:  4321:0:1:2:3:4:567:89ab.
508:             * See RFCs 1886 and 2373.
509:             */
510:            private String decodeAAAA(int pos) {
511:                int[] addr6 = new int[8]; // the unsigned 16-bit words of the address
512:                for (int i = 0; i < 8; i++) {
513:                    addr6[i] = getUShort(pos);
514:                    pos += 2;
515:                }
516:
517:                // Find longest sequence of two or more zeros, to compress them.
518:                int curBase = -1;
519:                int curLen = 0;
520:                int bestBase = -1;
521:                int bestLen = 0;
522:                for (int i = 0; i < 8; i++) {
523:                    if (addr6[i] == 0) {
524:                        if (curBase == -1) { // new sequence
525:                            curBase = i;
526:                            curLen = 1;
527:                        } else { // extend sequence
528:                            ++curLen;
529:                            if ((curLen >= 2) && (curLen > bestLen)) {
530:                                bestBase = curBase;
531:                                bestLen = curLen;
532:                            }
533:                        }
534:                    } else { // not in sequence
535:                        curBase = -1;
536:                    }
537:                }
538:
539:                // If addr begins with at least 6 zeros and is not :: or ::1,
540:                // or with 5 zeros followed by 0xffff, use the text format for
541:                // IPv4-compatible or IPv4-mapped addresses.
542:                if (bestBase == 0) {
543:                    if ((bestLen == 6) || ((bestLen == 7) && (addr6[7] > 1))) {
544:                        return ("::" + decodeA(pos - 4));
545:                    } else if ((bestLen == 5) && (addr6[5] == 0xffff)) {
546:                        return ("::ffff:" + decodeA(pos - 4));
547:                    }
548:                }
549:
550:                // If bestBase != -1, compress zeros in [bestBase, bestBase+bestLen)
551:                boolean compress = (bestBase != -1);
552:
553:                StringBuffer buf = new StringBuffer(40);
554:                if (bestBase == 0) {
555:                    buf.append(':');
556:                }
557:                for (int i = 0; i < 8; i++) {
558:                    if (!compress || (i < bestBase)
559:                            || (i >= bestBase + bestLen)) {
560:                        buf.append(Integer.toHexString(addr6[i]));
561:                        if (i < 7) {
562:                            buf.append(':');
563:                        }
564:                    } else if (compress && (i == bestBase)) { // first compressed zero
565:                        buf.append(':');
566:                    }
567:                }
568:
569:                return buf.toString();
570:            }
571:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.