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