Dns server working for single test query issued by command line
This commit is contained in:
parent
0460c35e2e
commit
3587933022
98
src/dorkbox/network/dns/DnsServerResponse.java
Normal file
98
src/dorkbox/network/dns/DnsServerResponse.java
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
import dorkbox.network.dns.records.DnsMessage;
|
||||
import io.netty.channel.AddressedEnvelope;
|
||||
import io.netty.util.internal.UnstableApi;
|
||||
|
||||
/**
|
||||
* A {@link DnsServerResponse} implementation for UDP/IP.
|
||||
*/
|
||||
@UnstableApi
|
||||
public
|
||||
class DnsServerResponse extends DnsEnvelope {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param localAddress the address of the sender
|
||||
* @param remoteAddress the address of the recipient
|
||||
*/
|
||||
public
|
||||
DnsServerResponse(final DnsMessage dnsQuestion, InetSocketAddress localAddress, InetSocketAddress remoteAddress) {
|
||||
super(dnsQuestion.getHeader()
|
||||
.getID(), localAddress, remoteAddress);
|
||||
|
||||
if (remoteAddress == null && localAddress == null) {
|
||||
throw new NullPointerException("localAddress and remoteAddress");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
int hashCode() {
|
||||
int hashCode = super.hashCode();
|
||||
if (sender() != null) {
|
||||
hashCode = hashCode * 31 + sender().hashCode();
|
||||
}
|
||||
if (recipient() != null) {
|
||||
hashCode = hashCode * 31 + recipient().hashCode();
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(obj instanceof AddressedEnvelope)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final AddressedEnvelope<?, SocketAddress> that = (AddressedEnvelope<?, SocketAddress>) obj;
|
||||
if (sender() == null) {
|
||||
if (that.sender() != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!sender().equals(that.sender())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (recipient() == null) {
|
||||
if (that.recipient() != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!recipient().equals(that.recipient())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -22,16 +22,20 @@ import java.net.UnknownHostException;
|
|||
import org.slf4j.Logger;
|
||||
|
||||
import dorkbox.network.dns.DnsEnvelope;
|
||||
import dorkbox.network.dns.DnsServerResponse;
|
||||
import dorkbox.network.dns.Name;
|
||||
import dorkbox.network.dns.constants.DnsOpCode;
|
||||
import dorkbox.network.dns.constants.DnsRecordType;
|
||||
import dorkbox.network.dns.constants.DnsResponseCode;
|
||||
import dorkbox.network.dns.constants.DnsSection;
|
||||
import dorkbox.network.dns.records.*;
|
||||
import dorkbox.network.dns.records.ARecord;
|
||||
import dorkbox.network.dns.records.DnsMessage;
|
||||
import dorkbox.network.dns.records.DnsRecord;
|
||||
import dorkbox.network.dns.records.Header;
|
||||
import dorkbox.network.dns.records.Update;
|
||||
import dorkbox.util.collections.IntMap;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
|
||||
public class DnsDecisionHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
|
@ -62,10 +66,9 @@ public class DnsDecisionHandler extends ChannelInboundHandlerAdapter {
|
|||
public
|
||||
void channelRead(ChannelHandlerContext context, Object message) throws Exception {
|
||||
onChannelRead(context, (DnsEnvelope) message);
|
||||
ReferenceCountUtil.release(message);
|
||||
}
|
||||
|
||||
public
|
||||
private
|
||||
void onChannelRead(final ChannelHandlerContext context, final DnsEnvelope dnsMessage) {
|
||||
int opcode = dnsMessage.getHeader()
|
||||
.getOpcode();
|
||||
|
@ -73,32 +76,26 @@ public class DnsDecisionHandler extends ChannelInboundHandlerAdapter {
|
|||
switch (opcode) {
|
||||
case DnsOpCode.QUERY:
|
||||
onQuery(context, dnsMessage, dnsMessage.recipient());
|
||||
dnsMessage.release();
|
||||
return;
|
||||
|
||||
case DnsOpCode.IQUERY:
|
||||
onIQuery(context, dnsMessage, dnsMessage.recipient());
|
||||
dnsMessage.release();
|
||||
return;
|
||||
|
||||
case DnsOpCode.NOTIFY:
|
||||
onNotify(context, dnsMessage, dnsMessage.recipient());
|
||||
dnsMessage.release();
|
||||
return;
|
||||
|
||||
case DnsOpCode.STATUS:
|
||||
onStatus(context, dnsMessage, dnsMessage.recipient());
|
||||
dnsMessage.release();
|
||||
return;
|
||||
|
||||
case DnsOpCode.UPDATE:
|
||||
onUpdate(context, (Update) (DnsMessage) dnsMessage, dnsMessage.recipient());
|
||||
dnsMessage.release();
|
||||
return;
|
||||
|
||||
default:
|
||||
logger.error("Unknown DNS opcode {} from {}", opcode, context.channel().remoteAddress());
|
||||
dnsMessage.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,12 +108,11 @@ public class DnsDecisionHandler extends ChannelInboundHandlerAdapter {
|
|||
|
||||
// we don't support more than 1 question at a time.
|
||||
if (count == 1) {
|
||||
DnsEnvelope dnsEnvelope = new DnsEnvelope(dnsQuestion.getHeader()
|
||||
.getID(),
|
||||
(InetSocketAddress) context.channel().localAddress(),
|
||||
recipient);
|
||||
DnsServerResponse dnsResponse = new DnsServerResponse(dnsQuestion,
|
||||
(InetSocketAddress) context.channel().localAddress(),
|
||||
recipient);
|
||||
|
||||
// dnsEnvelope.getHeader().setRcode(DnsResponseCode.NXDOMAIN);
|
||||
// dnsResponse.getHeader().setRcode(DnsResponseCode.NXDOMAIN);
|
||||
|
||||
DnsRecord[] sectionArray = dnsQuestion.getSectionArray(DnsSection.QUESTION);
|
||||
DnsRecord dnsRecord = sectionArray[0];
|
||||
|
@ -127,22 +123,16 @@ public class DnsDecisionHandler extends ChannelInboundHandlerAdapter {
|
|||
// // what type of record? A, AAAA, MX, PTR, etc?
|
||||
if (DnsRecordType.A == type) {
|
||||
ARecord answerRecord = new ARecord(name, dnsRecord.getDClass(), 10, localHost);
|
||||
dnsEnvelope.addRecord(dnsRecord, DnsSection.QUESTION);
|
||||
dnsEnvelope.addRecord(answerRecord, DnsSection.ANSWER);
|
||||
dnsResponse.addRecord(dnsRecord, DnsSection.QUESTION);
|
||||
dnsResponse.addRecord(answerRecord, DnsSection.ANSWER);
|
||||
|
||||
dnsEnvelope.getHeader().setRcode(DnsResponseCode.NOERROR);
|
||||
dnsResponse.getHeader().setRcode(DnsResponseCode.NOERROR);
|
||||
|
||||
System.err.println("write");
|
||||
logger.debug("Writing A record response: {}", answerRecord.getAddress());
|
||||
}
|
||||
|
||||
// dnsEnvelope.retain();
|
||||
// NOTE: I suspect this must be a "client" that writes back. there are errors if not.
|
||||
context.channel()
|
||||
.writeAndFlush(dnsEnvelope);
|
||||
|
||||
|
||||
// out.add(new DatagramPacket(buf, recipient, null));
|
||||
|
||||
.write(dnsResponse);
|
||||
|
||||
|
||||
// ChannelBuffer buffer = (ChannelBuffer) e.getMessage();
|
||||
|
@ -292,7 +282,7 @@ public class DnsDecisionHandler extends ChannelInboundHandlerAdapter {
|
|||
@Override
|
||||
public
|
||||
void exceptionCaught(final ChannelHandlerContext context, final Throwable cause) throws Exception {
|
||||
logger.error("ForwardingHandler#exceptionCaught", cause);
|
||||
logger.error("DecisionHandler#exceptionCaught", cause);
|
||||
super.exceptionCaught(context, cause);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,10 +43,6 @@ class DnsMessageDecoder extends MessageToMessageDecoder<DatagramPacket> {
|
|||
InetSocketAddress remoteAddress = packet.sender();
|
||||
|
||||
DnsEnvelope dnsEnvelope = new DnsEnvelope(buf, localAddress, remoteAddress);
|
||||
dnsEnvelope.retain();
|
||||
|
||||
|
||||
// send down the pipeline
|
||||
out.add(dnsEnvelope);
|
||||
success = true;
|
||||
} finally {
|
||||
|
|
|
@ -1,25 +1,29 @@
|
|||
package dorkbox.network.dns.serverHandlers;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import dorkbox.network.dns.DnsOutput;
|
||||
import dorkbox.network.dns.records.DnsMessage;
|
||||
import dorkbox.network.dns.DnsServerResponse;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.socket.DatagramPacket;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
|
||||
/**
|
||||
* An encoder which serializes a Java object into a {@link ByteBuf}.
|
||||
* <p>
|
||||
* Please note that the serialized form this encoder produces is not
|
||||
* compatible with the standard {@link ObjectInputStream}. Please use
|
||||
* {@link ObjectDecoder} or {@link ObjectDecoderInputStream} to ensure the
|
||||
* interoperability with this encoder.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public
|
||||
class DnsMessageEncoder extends MessageToByteEncoder<DnsMessage> {
|
||||
class DnsMessageEncoder extends MessageToByteEncoder<DnsServerResponse> {
|
||||
private final Logger logger;
|
||||
|
||||
public
|
||||
DnsMessageEncoder(final Logger logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
|
||||
// public
|
||||
|
@ -54,23 +58,24 @@ class DnsMessageEncoder extends MessageToByteEncoder<DnsMessage> {
|
|||
|
||||
@Override
|
||||
protected
|
||||
void encode(final ChannelHandlerContext ctx, final DnsMessage msg, final ByteBuf out) throws Exception {
|
||||
System.err.println("WRITING MESSAGE");
|
||||
final DnsOutput outd = new DnsOutput(out);
|
||||
msg.toWire(outd);
|
||||
void encode(final ChannelHandlerContext context, final DnsServerResponse message, final ByteBuf out) throws Exception {
|
||||
try {
|
||||
DnsOutput dnsOutput = new DnsOutput(out);
|
||||
out.retain();
|
||||
message.toWire(dnsOutput);
|
||||
|
||||
DatagramPacket packet = new DatagramPacket(out, message.recipient(), message.sender());
|
||||
context.channel()
|
||||
.writeAndFlush(packet);
|
||||
} catch (Exception e) {
|
||||
context.fireExceptionCaught(new IOException("Unable to write dns message: " + message, e));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception {
|
||||
// Channel channel = context.channel();
|
||||
|
||||
System.err.println("POW! ");
|
||||
cause.printStackTrace();
|
||||
// this.logger.error("Unexpected exception while trying to send/receive data on Client remote (network) channel. ({})" +
|
||||
// System.getProperty("line.separator"), channel.remoteAddress(), cause);
|
||||
// if (channel.isOpen()) {
|
||||
// channel.close();
|
||||
// }
|
||||
void exceptionCaught(final ChannelHandlerContext context, final Throwable cause) throws Exception {
|
||||
logger.error("DnsMessageEncoder#exceptionCaught", cause);
|
||||
super.exceptionCaught(context, cause);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,16 @@ public
|
|||
class DnsServerHandler extends ChannelInboundHandlerAdapter {
|
||||
protected final DnsMessageDecoder decoder;
|
||||
private final Logger logger;
|
||||
private DnsDecisionHandler decisionHandler;
|
||||
private DnsMessageEncoder encoder;
|
||||
|
||||
public
|
||||
DnsServerHandler(final Logger logger) {
|
||||
this.logger = logger;
|
||||
|
||||
decoder = new DnsMessageDecoder(logger);
|
||||
decisionHandler = new DnsDecisionHandler(logger);
|
||||
encoder = new DnsMessageEncoder(logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -49,12 +54,13 @@ class DnsServerHandler extends ChannelInboundHandlerAdapter {
|
|||
///////////////////////
|
||||
// DECODE (or upstream)
|
||||
///////////////////////
|
||||
pipeline.addLast("decoder", this.decoder);
|
||||
pipeline.addLast("decoder", decoder);
|
||||
pipeline.addLast("dnsDecision", decisionHandler);
|
||||
|
||||
// ENCODE (or downstream)
|
||||
/////////////////////////
|
||||
pipeline.addLast("dnsDecision", new DnsDecisionHandler(logger));
|
||||
pipeline.addLast("fowarder", new ForwardingHandler(logger));
|
||||
pipeline.addLast("encoder", encoder);
|
||||
// pipeline.addLast("fowarder", new ForwardingHandler(logger));
|
||||
// pipeline.addLast("fowarder", new ForwardingHandler(this.config, this.clientChannelFactory));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,19 @@
|
|||
package dorkbox.network.dns.serverHandlers;
|
||||
/*
|
||||
* 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.serverHandlers.wip;
|
||||
|
||||
import dorkbox.network.dns.DnsResponse;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
|
@ -1,15 +1,26 @@
|
|||
package dorkbox.network.dns.serverHandlers;
|
||||
|
||||
import java.io.IOException;
|
||||
/*
|
||||
* 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.serverHandlers.wip;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import dorkbox.network.dns.DnsEnvelope;
|
||||
import dorkbox.network.dns.DnsOutput;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.socket.DatagramPacket;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
|
||||
public class ForwardingHandler extends MessageToByteEncoder<DnsEnvelope> {
|
||||
|
@ -39,16 +50,19 @@ public class ForwardingHandler extends MessageToByteEncoder<DnsEnvelope> {
|
|||
void encode(final ChannelHandlerContext context, final DnsEnvelope message, final ByteBuf out) throws Exception {
|
||||
System.err.println("FORWARD HANDLER ENCODE");
|
||||
|
||||
try {
|
||||
DnsOutput dnsOutput = new DnsOutput(out);
|
||||
message.toWire(dnsOutput);
|
||||
// TODO: forward the message to ANOTHER dns server because we don't know what the awnser is
|
||||
|
||||
context.channel()
|
||||
.writeAndFlush(new DatagramPacket(out, message.recipient(), null));
|
||||
// .write(new DatagramPacket(out, message.recipient(), message.sender()));
|
||||
} catch (Exception e) {
|
||||
context.fireExceptionCaught(new IOException("Unable to write dns message: " + message, e));
|
||||
}
|
||||
// try {
|
||||
// DnsOutput dnsOutput = new DnsOutput(out);
|
||||
// message.toWire(dnsOutput);
|
||||
//
|
||||
// //todo: need void promise
|
||||
// context.channel()
|
||||
// .writeAndFlush(new DatagramPacket(out, message.recipient(), message.sender()));
|
||||
// // .write(new DatagramPacket(out, message.recipient(), message.sender()));
|
||||
// } catch (Exception e) {
|
||||
// context.fireExceptionCaught(new IOException("Unable to write dns message: " + message, e));
|
||||
// }
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +1,19 @@
|
|||
package dorkbox.network.dns.serverHandlers;
|
||||
/*
|
||||
* 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.serverHandlers.wip;
|
||||
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
|
@ -1,4 +1,19 @@
|
|||
package dorkbox.network.dns.serverHandlers;
|
||||
/*
|
||||
* 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.serverHandlers.wip;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
|
@ -7,7 +22,14 @@ import dorkbox.util.NamedThreadFactory;
|
|||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.PooledByteBufAllocator;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandler;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.oio.OioEventLoopGroup;
|
||||
import io.netty.channel.socket.DatagramPacket;
|
Loading…
Reference in New Issue
Block a user