diff --git a/src/dorkbox/network/dns/DnsServerResponse.java b/src/dorkbox/network/dns/DnsServerResponse.java new file mode 100644 index 00000000..0b3627de --- /dev/null +++ b/src/dorkbox/network/dns/DnsServerResponse.java @@ -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 that = (AddressedEnvelope) 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; + } +} diff --git a/src/dorkbox/network/dns/serverHandlers/DnsDecisionHandler.java b/src/dorkbox/network/dns/serverHandlers/DnsDecisionHandler.java index bbdacc08..19176c24 100644 --- a/src/dorkbox/network/dns/serverHandlers/DnsDecisionHandler.java +++ b/src/dorkbox/network/dns/serverHandlers/DnsDecisionHandler.java @@ -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); } diff --git a/src/dorkbox/network/dns/serverHandlers/DnsMessageDecoder.java b/src/dorkbox/network/dns/serverHandlers/DnsMessageDecoder.java index 247ffdd7..b82179da 100644 --- a/src/dorkbox/network/dns/serverHandlers/DnsMessageDecoder.java +++ b/src/dorkbox/network/dns/serverHandlers/DnsMessageDecoder.java @@ -43,10 +43,6 @@ class DnsMessageDecoder extends MessageToMessageDecoder { InetSocketAddress remoteAddress = packet.sender(); DnsEnvelope dnsEnvelope = new DnsEnvelope(buf, localAddress, remoteAddress); - dnsEnvelope.retain(); - - - // send down the pipeline out.add(dnsEnvelope); success = true; } finally { diff --git a/src/dorkbox/network/dns/serverHandlers/DnsMessageEncoder.java b/src/dorkbox/network/dns/serverHandlers/DnsMessageEncoder.java index 92709808..63e82ed2 100644 --- a/src/dorkbox/network/dns/serverHandlers/DnsMessageEncoder.java +++ b/src/dorkbox/network/dns/serverHandlers/DnsMessageEncoder.java @@ -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}. - *

- * 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 { +class DnsMessageEncoder extends MessageToByteEncoder { + private final Logger logger; + + public + DnsMessageEncoder(final Logger logger) { + this.logger = logger; + } // public @@ -54,23 +58,24 @@ class DnsMessageEncoder extends MessageToByteEncoder { @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); } } diff --git a/src/dorkbox/network/dns/serverHandlers/DnsServerHandler.java b/src/dorkbox/network/dns/serverHandlers/DnsServerHandler.java index bbfc8299..da6f3fe1 100644 --- a/src/dorkbox/network/dns/serverHandlers/DnsServerHandler.java +++ b/src/dorkbox/network/dns/serverHandlers/DnsServerHandler.java @@ -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)); } } diff --git a/src/dorkbox/network/dns/serverHandlers/DnsResponseHandler.java b/src/dorkbox/network/dns/serverHandlers/wip/DnsResponseHandler.java similarity index 68% rename from src/dorkbox/network/dns/serverHandlers/DnsResponseHandler.java rename to src/dorkbox/network/dns/serverHandlers/wip/DnsResponseHandler.java index 32db0cdb..577a0f35 100644 --- a/src/dorkbox/network/dns/serverHandlers/DnsResponseHandler.java +++ b/src/dorkbox/network/dns/serverHandlers/wip/DnsResponseHandler.java @@ -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; diff --git a/src/dorkbox/network/dns/serverHandlers/ForwardingHandler.java b/src/dorkbox/network/dns/serverHandlers/wip/ForwardingHandler.java similarity index 79% rename from src/dorkbox/network/dns/serverHandlers/ForwardingHandler.java rename to src/dorkbox/network/dns/serverHandlers/wip/ForwardingHandler.java index 36d64b9e..37782bed 100644 --- a/src/dorkbox/network/dns/serverHandlers/ForwardingHandler.java +++ b/src/dorkbox/network/dns/serverHandlers/wip/ForwardingHandler.java @@ -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 { @@ -39,16 +50,19 @@ public class ForwardingHandler extends MessageToByteEncoder { 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)); + // } } diff --git a/src/dorkbox/network/dns/serverHandlers/SuccessHandler.java b/src/dorkbox/network/dns/serverHandlers/wip/SuccessHandler.java similarity index 52% rename from src/dorkbox/network/dns/serverHandlers/SuccessHandler.java rename to src/dorkbox/network/dns/serverHandlers/wip/SuccessHandler.java index 53b75891..3142ef33 100644 --- a/src/dorkbox/network/dns/serverHandlers/SuccessHandler.java +++ b/src/dorkbox/network/dns/serverHandlers/wip/SuccessHandler.java @@ -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; diff --git a/src/dorkbox/network/dns/serverHandlers/aaaDNSMessageDecoderandForwarder.java b/src/dorkbox/network/dns/serverHandlers/wip/aaaDNSMessageDecoderandForwarder.java similarity index 87% rename from src/dorkbox/network/dns/serverHandlers/aaaDNSMessageDecoderandForwarder.java rename to src/dorkbox/network/dns/serverHandlers/wip/aaaDNSMessageDecoderandForwarder.java index c7c3f235..de8c026a 100644 --- a/src/dorkbox/network/dns/serverHandlers/aaaDNSMessageDecoderandForwarder.java +++ b/src/dorkbox/network/dns/serverHandlers/wip/aaaDNSMessageDecoderandForwarder.java @@ -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;