This commit is contained in:
nathan 2018-03-04 15:15:07 +01:00
parent 1f2b78da7d
commit 77b587a74f
16 changed files with 925 additions and 0 deletions

View File

@ -0,0 +1,42 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.server;
import dorkbox.network.dns.Name;
import dorkbox.network.dns.constants.DnsResponseCode;
import dorkbox.network.dns.records.DnsMessage;
import dorkbox.network.dns.records.DnsRecord;
public class CNAMEResponse extends DefaultResponse {
final Name cname;
final int qtype;
public CNAMEResponse(DnsRecord cname, int queryType) {
super(DnsResponseCode.NOERROR);
this.cname = cname.getName();
this.qtype = queryType;
}
@Override
public void postProcess(DnsMessage message) {
System.err.println("WHAT?");
// context.response().answer().add(this.cname);
// Response r = context.resolve(this.cname.oneName(), this.qtype);
// r.postProcess(context);
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.server;
import dorkbox.network.dns.Name;
import dorkbox.network.dns.constants.DnsResponseCode;
import dorkbox.network.dns.records.DnsMessage;
import dorkbox.network.dns.records.DnsRecord;
public class DNAMEResponse extends DefaultResponse {
final Name dname;
final Name qname;
final int qtype;
public DNAMEResponse(DnsRecord dname, Name qname, int qtype) {
super(DnsResponseCode.NOERROR);
this.dname = dname.getName();
this.qname = qname;
this.qtype = qtype;
}
@Override
public void postProcess(DnsMessage context) {
System.err.println("WWHAT?");
// DNSMessage res = context.response();
// res.answer().add(this.dname);
// Name name = this.qname.replace(this.dname.name(), this.dname.oneName());
// if (name == null) {
// context.response().header().rcode(RCode.YXDomain);
// } else {
// SingleNameRecord cname = new SingleNameRecord(RRType.CNAME, name);
// cname.name(this.qname);
// res.answer().add(cname);
// res.header().aa(true);
// Response r = context.resolve(name, this.qtype);
// r.postProcess(context);
// }
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.server;
/**
*
*/
public abstract
class DefaultResponse implements Response {
private final int responseCode;
public
DefaultResponse(int responseCode) {
this.responseCode = responseCode;
}
@Override
public
int responseCode() {
return responseCode;
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.server;
import java.util.Set;
import dorkbox.network.dns.constants.DnsResponseCode;
import dorkbox.network.dns.constants.DnsSection;
import dorkbox.network.dns.constants.Flags;
import dorkbox.network.dns.records.DnsMessage;
import dorkbox.network.dns.records.DnsRecord;
public
class NoErrorResponse extends DefaultResponse {
final Set<DnsRecord> records;
final boolean authoritativeAnswer;
public
NoErrorResponse(Set<DnsRecord> records) {
this(records, true);
}
public
NoErrorResponse(Set<DnsRecord> records, boolean authoritativeAnswer) {
super(DnsResponseCode.NOERROR);
this.records = records;
this.authoritativeAnswer = authoritativeAnswer;
}
@Override
public
void postProcess(DnsMessage message) {
message.getHeader()
.setRcode(this.responseCode());
message.getHeader()
.setFlag(Flags.QR);
if (this.authoritativeAnswer) {
message.getHeader()
.setFlag(Flags.AA);
}
else {
message.getHeader()
.unsetFlag(Flags.AA);
}
for (DnsRecord record : records) {
message.addRecord(record, DnsSection.ANSWER);
}
// TODO additional section ?
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.server;
import dorkbox.network.dns.constants.DnsSection;
import dorkbox.network.dns.records.DnsMessage;
import dorkbox.network.dns.records.SOARecord;
/**
*
*/
public
class NotFoundResponse extends DefaultResponse {
final SOARecord soaRecord;
public
NotFoundResponse(int rcode, SOARecord soaRecord) {
super(rcode);
this.soaRecord = soaRecord;
}
@Override
public
void postProcess(DnsMessage message) {
message.getHeader().setRcode(this.responseCode());
message.addRecord(this.soaRecord, DnsSection.AUTHORITY);
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.server;
import java.util.Set;
import dorkbox.network.dns.constants.DnsResponseCode;
import dorkbox.network.dns.constants.DnsSection;
import dorkbox.network.dns.records.DnsMessage;
import dorkbox.network.dns.records.DnsRecord;
public class ReferralResponse extends DefaultResponse {
final Set<DnsRecord> nsRecords;
public ReferralResponse(Set<DnsRecord> records) {
super(DnsResponseCode.NOERROR);
this.nsRecords = records;
}
@Override
public void postProcess(DnsMessage message) {
message.getHeader().setRcode(this.responseCode());
for (DnsRecord nsRecord : nsRecords) {
message.addRecord(nsRecord, DnsSection.AUTHORITY);
}
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.server;
import dorkbox.network.dns.records.DnsMessage;
/**
*
*/
public
interface Response {
int responseCode();
void postProcess(DnsMessage message);
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.zone;
import dorkbox.network.dns.Name;
import dorkbox.network.dns.constants.DnsClass;
public abstract class AbstractZone implements Zone {
protected ZoneType type;
protected int dnsClass;
protected Name name;
public AbstractZone(ZoneType type, Name name) {
this(type, DnsClass.IN, name);
}
public AbstractZone(ZoneType type, int dnsClass, Name name) {
this.type = type;
this.dnsClass = dnsClass;
this.name = name;
}
@Override
public ZoneType type() {
return this.type;
}
@Override
public int dnsClass() {
return this.dnsClass;
}
@Override
public Name name() {
return this.name;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.zone;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import dorkbox.network.dns.Name;
import dorkbox.network.dns.server.Response;
public class ForwardZone extends AbstractZone {
protected List<InetAddress> forwarders = new ArrayList<InetAddress>();
public ForwardZone(Name name) {
super(ZoneType.forward, name);
}
public ForwardZone(int dnsclass, Name name) {
super(ZoneType.forward, dnsclass, name);
}
public void addForwardHost(InetAddress host) {
this.forwarders.add(host);
}
@Override
public
Response find(Name qname, int recordType) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,211 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.zone;
import java.util.HashSet;
import java.util.NavigableSet;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ConcurrentSkipListSet;
import dorkbox.network.dns.Name;
import dorkbox.network.dns.constants.DnsRecordType;
import dorkbox.network.dns.constants.DnsResponseCode;
import dorkbox.network.dns.records.DnsRecord;
import dorkbox.network.dns.records.SOARecord;
import dorkbox.network.dns.server.CNAMEResponse;
import dorkbox.network.dns.server.DNAMEResponse;
import dorkbox.network.dns.server.NoErrorResponse;
import dorkbox.network.dns.server.NotFoundResponse;
import dorkbox.network.dns.server.ReferralResponse;
import dorkbox.network.dns.server.Response;
public
class MasterZone extends AbstractZone {
final ConcurrentMap<Name, ConcurrentMap<Integer, NavigableSet<DnsRecord>>> records = new ConcurrentSkipListMap<Name, ConcurrentMap<Integer, NavigableSet<DnsRecord>>>();
final Response nxDomain;
final Response nxRRSet;
public
MasterZone(Name name, SOARecord soaRecord) {
super(ZoneType.master, name);
this.nxDomain = new NotFoundResponse(DnsResponseCode.NXDOMAIN, soaRecord);
this.nxRRSet = new NotFoundResponse(DnsResponseCode.NXRRSET, soaRecord);
}
// add and remove needs queuing?
// if modify operations works on single thread, not conflict.
public synchronized
void add(DnsRecord rr) {
for (; ; ) {
ConcurrentMap<Integer, NavigableSet<DnsRecord>> current = this.records.get(rr.getName());
if (current == null) {
ConcurrentMap<Integer, NavigableSet<DnsRecord>> newone = new ConcurrentSkipListMap<Integer, NavigableSet<DnsRecord>>();
NavigableSet<DnsRecord> newset = new ConcurrentSkipListSet<DnsRecord>();
newset.add(rr);
newone.put(rr.getType(), newset);
ConcurrentMap<Integer, NavigableSet<DnsRecord>> prevTypes = this.records.putIfAbsent(rr.getName(), newone);
if (prevTypes == null) {
break;
}
synchronized (prevTypes) {
Set<DnsRecord> prevRecs = prevTypes.putIfAbsent(rr.getType(), newset);
if (prevRecs == null) {
break;
}
prevRecs.add(rr);
break;
}
}
else {
synchronized (current) {
Set<DnsRecord> rrs = current.get(rr.getType());
if (rrs == null) {
NavigableSet<DnsRecord> newset = new ConcurrentSkipListSet<DnsRecord>();
newset.add(rr);
current.put(rr.getType(), newset);
break;
}
if (!rrs.isEmpty()) {
rrs.add(rr);
break;
}
}
}
}
}
@Override
public
Response find(Name queryName, int recordType) {
if (!queryName.equals(this.name)) {
return this.nxDomain;
}
ConcurrentMap<Integer, NavigableSet<DnsRecord>> exactMatch = this.records.get(queryName);
if (exactMatch != null) {
NavigableSet<DnsRecord> rrs = exactMatch.get(recordType);
if (rrs != null) {
synchronized (rrs) {
if (rrs.isEmpty()) {
return new NoErrorResponse(rrs);
}
}
}
if (DnsRecordType.ANY == recordType) {
Set<DnsRecord> newset = new HashSet<DnsRecord>();
for (Integer type : exactMatch.keySet()) {
Set<DnsRecord> s = exactMatch.get(type);
if (s != null) {
synchronized (s) {
newset.addAll(s);
}
}
}
if (newset.isEmpty()) {
return null;
}
}
if (DnsRecordType.CNAME == recordType) {
rrs = exactMatch.get(DnsRecordType.CNAME);
if (rrs != null) {
synchronized (rrs) {
if (!rrs.isEmpty()) {
return new CNAMEResponse(rrs.first(), recordType);
}
}
}
}
return this.nxRRSet;
}
for (Name qn = queryName.parent(1); !this.name()
.equals(qn); qn = qn.parent(1)) {
ConcurrentMap<Integer, NavigableSet<DnsRecord>> match = this.records.get(qn);
if (match != null) {
synchronized (match) {
if (!match.isEmpty()) {
NavigableSet<DnsRecord> set = match.get(DnsRecordType.NS);
if ((set != null) && (!set.isEmpty())) {
return new ReferralResponse(set);
}
set = match.get(DnsRecordType.DNAME);
if ((set != null) && (!set.isEmpty())) {
return new DNAMEResponse(set.first(), queryName, recordType);
}
}
}
}
}
for (Name qn = queryName; !this.name()
.equals(qn); qn = qn.parent(1)) {
Name wild = qn.wild(1);
ConcurrentMap<Integer, NavigableSet<DnsRecord>> match = this.records.get(wild);
if (match != null) {
synchronized (match) {
if (!match.isEmpty()) {
Set<DnsRecord> matchSet = match.get(recordType);
if (!matchSet.isEmpty()) {
Set<DnsRecord> set = new HashSet<DnsRecord>(matchSet.size());
for (DnsRecord rr : matchSet) {
set.add(DnsRecord.newRecord(queryName, rr.getType(), rr.getDClass(), rr.getTTL()));
}
return new NoErrorResponse(set);
}
}
}
}
}
return this.nxDomain;
}
public synchronized
void remove(DnsRecord rr, boolean checkSets, boolean checkMap) {
ConcurrentMap<Integer, NavigableSet<DnsRecord>> current = this.records.get(rr.getName());
if (current != null) {
synchronized (current) {
NavigableSet<DnsRecord> sets = current.get(rr.getType());
sets.remove(rr);
if (checkSets && sets.isEmpty()) {
current.remove(rr.getType());
if (checkMap && current.isEmpty()) {
this.records.remove(rr.getName());
}
}
}
}
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.zone;
import java.util.List;
import dorkbox.network.dns.Name;
import dorkbox.network.dns.records.DnsRecord;
/**
* @author taichi
*/
public
class Query {
protected Name origin;
protected Name current;
protected int dnsClass;
protected Zone target;
protected ZoneDatabase database;
public
Query(Name origin, Name current, int dnsClass, Zone target, ZoneDatabase database) {
super();
this.origin = origin;
this.current = current;
this.dnsClass = dnsClass;
this.target = target;
this.database = database;
}
protected
boolean contains(List<DnsRecord> rrs) {
for (DnsRecord rr : rrs) {
if (this.origin.equals(rr.getName())) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.zone;
import java.util.List;
import dorkbox.network.dns.records.DnsRecord;
public class SearchResult {
public enum Status {
NXDOMAIN, SUCCESS
}
List<DnsRecord> rrs;
Status status = Status.NXDOMAIN;
public SearchResult(List<DnsRecord> rrs) {
super();
this.rrs = rrs;
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.zone;
import dorkbox.network.dns.Name;
import dorkbox.network.dns.server.Response;
public
interface Zone {
int dnsClass();
Response find(Name qname, int recordType);
Name name();
ZoneType type();
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.zone;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;
import dorkbox.network.dns.Name;
public
class ZoneDatabase {
protected Map<ZoneDatabaseKey, Zone> zones = new ConcurrentSkipListMap<ZoneDatabaseKey, Zone>();
public
void add(Zone zone/* TODO ZoneConfig? */) {
this.zones.put(new ZoneDatabaseKey(zone), zone);
}
public
Query prepare(Name name, int dnsClass) {
ZoneDatabaseKey zk = new ZoneDatabaseKey(name, dnsClass);
Zone found = this.zones.get(zk);
if (found != null) {
// exact match
return new Query(name, name, dnsClass, found, this);
}
Name child = name;
// partial match
for (int i = 0, size = this.zones.size(); i < size; i++) {
Name p = child.parent(1);
zk.name(p);
found = this.zones.get(zk);
if (found == null) {
if (p.labels() <= 1) {
break;
}
child = p;
}
else {
return new Query(name, p, dnsClass, found, this);
}
}
// not found.
return null;
}
}

View File

@ -0,0 +1,95 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.zone;
import dorkbox.network.dns.Name;
import dorkbox.network.dns.records.DnsRecord;
/**
*
*/
class ZoneDatabaseKey implements Comparable<ZoneDatabaseKey> {
Name name;
int dnsclass;
public
ZoneDatabaseKey(Zone z) {
this(z.name(), z.dnsClass());
}
public
ZoneDatabaseKey(DnsRecord rr) {
this(rr.getName(), rr.getDClass());
}
public
ZoneDatabaseKey(Name name, int dnsclass) {
this.name = name;
this.dnsclass = dnsclass;
}
@Override
public
int compareTo(ZoneDatabaseKey o) {
if (o == null) {
return 1;
}
if (equals(o)) {
return 0;
}
return this.hashCode() - o.hashCode();
}
public
boolean equals(ZoneDatabaseKey other) {
return (this.dnsclass == other.dnsclass) && this.name.equals(other.name);
}
@Override
public
boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null) {
return false;
}
if (getClass() != other.getClass()) {
return false;
}
return equals((ZoneDatabaseKey) other);
}
@Override
public
int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.dnsclass;
result = prime * result + this.name.hashCode();
return result;
}
public
Name name() {
return this.name;
}
public
void name(Name name) {
this.name = name;
}
}

View File

@ -0,0 +1,21 @@
/*
* Copyright 2018 dorkbox, llc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.network.dns.zone;
public
enum ZoneType {
master, slave, stub, forward, rootHint
}