?? zone.java
字號(hào):
// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)package org.xbill.DNS;import java.io.*;import java.util.*;/** * A DNS Zone. This encapsulates all data related to a Zone, and provides * convenient lookup methods. * * @author Brian Wellington */public class Zone {/** A primary zone */public static final int PRIMARY = 1;/** A secondary zone */public static final int SECONDARY = 2;private Map data;private int type;private Name origin;private Object originNode;private int dclass = DClass.IN;private RRset NS;private SOARecord SOA;private boolean hasWild;class ZoneIterator implements Iterator { private Iterator zentries; private RRset [] current; private int count; private boolean wantLastSOA; ZoneIterator(boolean axfr) { zentries = data.entrySet().iterator(); wantLastSOA = axfr; RRset [] sets = allRRsets(originNode); current = new RRset[sets.length]; for (int i = 0, j = 2; i < sets.length; i++) { int type = sets[i].getType(); if (type == Type.SOA) current[0] = sets[i]; else if (type == Type.NS) current[1] = sets[i]; else current[j++] = sets[i]; } } public boolean hasNext() { return (current != null || wantLastSOA); } public Object next() { if (!hasNext()) { throw new NoSuchElementException(); } if (current == null && wantLastSOA) { wantLastSOA = false; return oneRRset(originNode, Type.SOA); } Object set = current[count++]; if (count == current.length) { current = null; while (zentries.hasNext()) { Map.Entry entry = (Map.Entry) zentries.next(); if (entry.getKey().equals(origin)) continue; RRset [] sets = allRRsets(entry.getValue()); if (sets.length == 0) continue; current = sets; count = 0; break; } } return set; } public void remove() { throw new UnsupportedOperationException(); }}private voidvalidate() throws IOException { originNode = exactName(origin); if (originNode == null) throw new IOException(origin + ": no data specified"); RRset rrset = oneRRset(originNode, Type.SOA); if (rrset == null || rrset.size() != 1) throw new IOException(origin + ": exactly 1 SOA must be specified"); Iterator it = rrset.rrs(); SOA = (SOARecord) it.next(); NS = oneRRset(originNode, Type.NS); if (NS == null) throw new IOException(origin + ": no NS set specified");}private final voidmaybeAddRecord(Record record) throws IOException { int type = record.getType(); Name name = record.getName(); if (type == Type.SOA && !name.equals(origin)) { throw new IOException("SOA owner " + name + " does not match zone origin " + origin); } if (name.subdomain(origin)) addRecord(record);}/** * Creates a Zone from the records in the specified master file. * @param zone The name of the zone. * @param file The master file to read from. * @see Master */publicZone(Name zone, String file) throws IOException { data = new HashMap(); type = PRIMARY; if (zone == null) throw new IllegalArgumentException("no zone name specified"); Master m = new Master(file, zone); Record record; origin = zone; while ((record = m.nextRecord()) != null) maybeAddRecord(record); validate();}/** * Creates a Zone from an array of records. * @param zone The name of the zone. * @param records The records to add to the zone. * @see Master */publicZone(Name zone, Record [] records) throws IOException { data = new HashMap(); type = PRIMARY; if (zone == null) throw new IllegalArgumentException("no zone name specified"); origin = zone; for (int i = 0; i < records.length; i++) maybeAddRecord(records[i]); validate();}private voidfromXFR(ZoneTransferIn xfrin) throws IOException, ZoneTransferException { data = new HashMap(); type = SECONDARY; if (xfrin.getType() != Type.AXFR) throw new IllegalArgumentException("zones can only be " + "created from AXFRs"); origin = xfrin.getName(); List records = xfrin.run(); for (Iterator it = records.iterator(); it.hasNext(); ) { Record record = (Record) it.next(); maybeAddRecord(record); } validate();}/** * Creates a Zone by doing the specified zone transfer. * @param xfrin The incoming zone transfer to execute. * @see ZoneTransferIn */publicZone(ZoneTransferIn xfrin) throws IOException, ZoneTransferException { fromXFR(xfrin);}/** * Creates a Zone by performing a zone transfer to the specified host. * @see ZoneTransferIn */publicZone(Name zone, int dclass, String remote)throws IOException, ZoneTransferException{ ZoneTransferIn xfrin = ZoneTransferIn.newAXFR(zone, remote, null); xfrin.setDClass(dclass); fromXFR(xfrin);}/** Returns the Zone's origin */public NamegetOrigin() { return origin;}/** Returns the Zone origin's NS records */public RRsetgetNS() { return NS;}/** Returns the Zone's SOA record */public SOARecordgetSOA() { return SOA;}/** Returns the Zone's class */public intgetDClass() { return dclass;}private synchronized ObjectexactName(Name name) { return data.get(name);}private synchronized RRset []allRRsets(Object types) { if (types instanceof List) { List typelist = (List) types; return (RRset []) typelist.toArray(new RRset[typelist.size()]); } else { RRset set = (RRset) types; return new RRset [] {set}; }}private synchronized RRsetoneRRset(Object types, int type) { if (type == Type.ANY) throw new IllegalArgumentException("oneRRset(ANY)"); if (types instanceof List) { List list = (List) types; for (int i = 0; i < list.size(); i++) { RRset set = (RRset) list.get(i); if (set.getType() == type) return set; } } else { RRset set = (RRset) types; if (set.getType() == type) return set; } return null;}private synchronized RRsetfindRRset(Name name, int type) { Object types = exactName(name); if (types == null) return null; return oneRRset(types, type);}private synchronized voidaddRRset(Name name, RRset rrset) { if (!hasWild && name.isWild()) hasWild = true; Object types = data.get(name); if (types == null) { data.put(name, rrset); return; } int type = rrset.getType(); if (types instanceof List) { List list = (List) types; for (int i = 0; i < list.size(); i++) { RRset set = (RRset) list.get(i); if (set.getType() == type) { list.set(i, rrset); return; } } list.add(rrset); } else { RRset set = (RRset) types; if (set.getType() == type) data.put(name, rrset); else { LinkedList list = new LinkedList(); list.add(set); list.add(rrset); data.put(name, list); } }}private synchronized voidremoveRRset(Name name, int type) { Object types = data.get(name); if (types == null) { return; } if (types instanceof List) { List list = (List) types; for (int i = 0; i < list.size(); i++) { RRset set = (RRset) list.get(i); if (set.getType() == type) { list.remove(i); if (list.size() == 0) data.remove(name); return; } } } else { RRset set = (RRset) types; if (set.getType() != type) return; data.remove(name); }}private synchronized SetResponselookup(Name name, int type) { int labels; int olabels; int tlabels; RRset rrset; Name tname; Object types; SetResponse sr; if (!name.subdomain(origin)) return SetResponse.ofType(SetResponse.NXDOMAIN); labels = name.labels(); olabels = origin.labels(); for (tlabels = olabels; tlabels <= labels; tlabels++) { boolean isOrigin = (tlabels == olabels); boolean isExact = (tlabels == labels); if (isOrigin) tname = origin; else if (isExact) tname = name; else tname = new Name(name, labels - tlabels); types = exactName(tname); if (types == null) continue; /* If this is a delegation, return that. */ if (!isOrigin) { RRset ns = oneRRset(types, Type.NS); if (ns != null) return new SetResponse(SetResponse.DELEGATION, ns); } /* If this is an ANY lookup, return everything. */ if (isExact && type == Type.ANY) { sr = new SetResponse(SetResponse.SUCCESSFUL); RRset [] sets = allRRsets(types); for (int i = 0; i < sets.length; i++) sr.addRRset(sets[i]); return sr; } /* * If this is the name, look for the actual type or a CNAME. * Otherwise, look for a DNAME. */ if (isExact) { rrset = oneRRset(types, type); if (rrset != null) { sr = new SetResponse(SetResponse.SUCCESSFUL); sr.addRRset(rrset); return sr; } rrset = oneRRset(types, Type.CNAME); if (rrset != null) return new SetResponse(SetResponse.CNAME, rrset); } else { rrset = oneRRset(types, Type.DNAME); if (rrset != null) return new SetResponse(SetResponse.DNAME, rrset); } /* We found the name, but not the type. */ if (isExact) return SetResponse.ofType(SetResponse.NXRRSET); } if (hasWild) { for (int i = 0; i < labels - olabels; i++) { tname = name.wild(i + 1); types = exactName(tname); if (types == null) continue; rrset = oneRRset(types, type); if (rrset != null) { sr = new SetResponse(SetResponse.SUCCESSFUL); sr.addRRset(rrset); return sr; } } } return SetResponse.ofType(SetResponse.NXDOMAIN);}/** * Looks up Records in the Zone. This follows CNAMEs and wildcards. * @param name The name to look up * @param type The type to look up * @return A SetResponse object * @see SetResponse */ public SetResponsefindRecords(Name name, int type) { return lookup(name, type);}/** * Looks up Records in the zone, finding exact matches only. * @param name The name to look up * @param type The type to look up * @return The matching RRset * @see RRset */ public RRsetfindExactMatch(Name name, int type) { return oneRRset(exactName(name), type);}/** * Adds an RRset to the Zone * @param rrset The RRset to be added * @see RRset */public voidaddRRset(RRset rrset) { Name name = rrset.getName(); addRRset(name, rrset);}/** * Adds a Record to the Zone * @param r The record to be added * @see Record */public voidaddRecord(Record r) { Name name = r.getName(); int type = r.getRRsetType(); synchronized (this) { RRset rrset = findRRset(name, type); if (rrset == null) rrset = new RRset(r); addRRset(name, rrset); }}/** * Removes a record from the Zone * @param r The record to be removed * @see Record */public voidremoveRecord(Record r) { Name name = r.getName(); int type = r.getRRsetType(); synchronized (this) { RRset rrset = findRRset(name, type); if (rrset == null) return; rrset.deleteRR(r); if (rrset.size() == 0) removeRRset(name, type); }}/** * Returns an Iterator over the RRsets in the zone. */public Iteratoriterator() { return new ZoneIterator(false);}/** * Returns an Iterator over the RRsets in the zone that can be used to * construct an AXFR response. This is identical to {@link #iterator} except * that the SOA is returned at the end as well as the beginning. */public IteratorAXFR() { return new ZoneIterator(true);}private voidnodeToString(StringBuffer sb, Object node) { RRset [] sets = allRRsets(node); for (int i = 0; i < sets.length; i++) { RRset rrset = sets[i]; Iterator it = rrset.rrs(); while (it.hasNext()) sb.append(it.next() + "\n"); it = rrset.sigs(); while (it.hasNext()) sb.append(it.next() + "\n"); }}/** * Returns the contents of the Zone in master file format. */public StringtoMasterFile() { Iterator zentries = data.entrySet().iterator(); StringBuffer sb = new StringBuffer(); nodeToString(sb, originNode); while (zentries.hasNext()) { Map.Entry entry = (Map.Entry) zentries.next(); if (!origin.equals(entry.getKey())) nodeToString(sb, entry.getValue()); } return sb.toString();}/** * Returns the contents of the Zone as a string (in master file format). */public StringtoString() { return toMasterFile();}}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -