WIP Zone
This commit is contained in:
parent
1f2b78da7d
commit
77b587a74f
42
src/dorkbox/network/dns/server/CNAMEResponse.java
Normal file
42
src/dorkbox/network/dns/server/CNAMEResponse.java
Normal 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);
|
||||
}
|
||||
}
|
54
src/dorkbox/network/dns/server/DNAMEResponse.java
Normal file
54
src/dorkbox/network/dns/server/DNAMEResponse.java
Normal 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);
|
||||
// }
|
||||
}
|
||||
}
|
35
src/dorkbox/network/dns/server/DefaultResponse.java
Normal file
35
src/dorkbox/network/dns/server/DefaultResponse.java
Normal 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;
|
||||
}
|
||||
}
|
67
src/dorkbox/network/dns/server/NoErrorResponse.java
Normal file
67
src/dorkbox/network/dns/server/NoErrorResponse.java
Normal 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 ?
|
||||
}
|
||||
}
|
42
src/dorkbox/network/dns/server/NotFoundResponse.java
Normal file
42
src/dorkbox/network/dns/server/NotFoundResponse.java
Normal 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);
|
||||
}
|
||||
}
|
41
src/dorkbox/network/dns/server/ReferralResponse.java
Normal file
41
src/dorkbox/network/dns/server/ReferralResponse.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
28
src/dorkbox/network/dns/server/Response.java
Normal file
28
src/dorkbox/network/dns/server/Response.java
Normal 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);
|
||||
}
|
54
src/dorkbox/network/dns/zone/AbstractZone.java
Normal file
54
src/dorkbox/network/dns/zone/AbstractZone.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
47
src/dorkbox/network/dns/zone/ForwardZone.java
Normal file
47
src/dorkbox/network/dns/zone/ForwardZone.java
Normal 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;
|
||||
}
|
||||
}
|
211
src/dorkbox/network/dns/zone/MasterZone.java
Normal file
211
src/dorkbox/network/dns/zone/MasterZone.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
59
src/dorkbox/network/dns/zone/Query.java
Normal file
59
src/dorkbox/network/dns/zone/Query.java
Normal 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;
|
||||
}
|
||||
}
|
36
src/dorkbox/network/dns/zone/SearchResult.java
Normal file
36
src/dorkbox/network/dns/zone/SearchResult.java
Normal 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;
|
||||
}
|
||||
}
|
30
src/dorkbox/network/dns/zone/Zone.java
Normal file
30
src/dorkbox/network/dns/zone/Zone.java
Normal 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();
|
||||
}
|
63
src/dorkbox/network/dns/zone/ZoneDatabase.java
Normal file
63
src/dorkbox/network/dns/zone/ZoneDatabase.java
Normal 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;
|
||||
}
|
||||
}
|
95
src/dorkbox/network/dns/zone/ZoneDatabaseKey.java
Normal file
95
src/dorkbox/network/dns/zone/ZoneDatabaseKey.java
Normal 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;
|
||||
}
|
||||
}
|
21
src/dorkbox/network/dns/zone/ZoneType.java
Normal file
21
src/dorkbox/network/dns/zone/ZoneType.java
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user