Search in sources :

Example 1 with DnsMessageEncoder

use of org.apache.directory.server.dns.io.encoder.DnsMessageEncoder in project netty by netty.

the class DnsNameResolverTest method testTruncated0.

private static void testTruncated0(boolean tcpFallback, final boolean truncatedBecauseOfMtu) throws IOException {
    final String host = "somehost.netty.io";
    final String txt = "this is a txt record";
    final AtomicReference<DnsMessage> messageRef = new AtomicReference<DnsMessage>();
    TestDnsServer dnsServer2 = new TestDnsServer(new RecordStore() {

        @Override
        public Set<ResourceRecord> getRecords(QuestionRecord question) {
            String name = question.getDomainName();
            if (name.equals(host)) {
                return Collections.<ResourceRecord>singleton(new TestDnsServer.TestResourceRecord(name, RecordType.TXT, Collections.<String, Object>singletonMap(DnsAttribute.CHARACTER_STRING.toLowerCase(), txt)));
            }
            return null;
        }
    }) {

        @Override
        protected DnsMessage filterMessage(DnsMessage message) {
            // Store a original message so we can replay it later on.
            messageRef.set(message);
            if (!truncatedBecauseOfMtu) {
                // Create a copy of the message but set the truncated flag.
                DnsMessageModifier modifier = modifierFrom(message);
                modifier.setTruncated(true);
                return modifier.getDnsMessage();
            }
            return message;
        }
    };
    dnsServer2.start();
    DnsNameResolver resolver = null;
    ServerSocket serverSocket = null;
    try {
        DnsNameResolverBuilder builder = newResolver().queryTimeoutMillis(10000).resolvedAddressTypes(ResolvedAddressTypes.IPV4_PREFERRED).maxQueriesPerResolve(16).nameServerProvider(new SingletonDnsServerAddressStreamProvider(dnsServer2.localAddress()));
        if (tcpFallback) {
            // If we are configured to use TCP as a fallback also bind a TCP socket
            serverSocket = new ServerSocket();
            serverSocket.setReuseAddress(true);
            serverSocket.bind(new InetSocketAddress(dnsServer2.localAddress().getPort()));
            builder.socketChannelType(NioSocketChannel.class);
        }
        resolver = builder.build();
        if (truncatedBecauseOfMtu) {
            resolver.ch.pipeline().addFirst(new ChannelInboundHandlerAdapter() {

                @Override
                public void channelRead(ChannelHandlerContext ctx, Object msg) {
                    if (msg instanceof DatagramPacket) {
                        // Truncate the packet by 1 byte.
                        DatagramPacket packet = (DatagramPacket) msg;
                        packet.content().writerIndex(packet.content().writerIndex() - 1);
                    }
                    ctx.fireChannelRead(msg);
                }
            });
        }
        Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> envelopeFuture = resolver.query(new DefaultDnsQuestion(host, DnsRecordType.TXT));
        if (tcpFallback) {
            // If we are configured to use TCP as a fallback lets replay the dns message over TCP
            Socket socket = serverSocket.accept();
            InputStream in = socket.getInputStream();
            // skip length field
            assertTrue((in.read() << 8 | (in.read() & 0xff)) > 2);
            int txnId = in.read() << 8 | (in.read() & 0xff);
            IoBuffer ioBuffer = IoBuffer.allocate(1024);
            // Must replace the transactionId with the one from the TCP request
            DnsMessageModifier modifier = modifierFrom(messageRef.get());
            modifier.setTransactionId(txnId);
            new DnsMessageEncoder().encode(ioBuffer, modifier.getDnsMessage());
            ioBuffer.flip();
            ByteBuffer lenBuffer = ByteBuffer.allocate(2);
            lenBuffer.putShort((short) ioBuffer.remaining());
            lenBuffer.flip();
            while (lenBuffer.hasRemaining()) {
                socket.getOutputStream().write(lenBuffer.get());
            }
            while (ioBuffer.hasRemaining()) {
                socket.getOutputStream().write(ioBuffer.get());
            }
            socket.getOutputStream().flush();
            // Let's wait until we received the envelope before closing the socket.
            envelopeFuture.syncUninterruptibly();
            socket.close();
            serverSocket.close();
        }
        AddressedEnvelope<DnsResponse, InetSocketAddress> envelope = envelopeFuture.syncUninterruptibly().getNow();
        assertNotNull(envelope.sender());
        DnsResponse response = envelope.content();
        assertNotNull(response);
        assertEquals(DnsResponseCode.NOERROR, response.code());
        int count = response.count(DnsSection.ANSWER);
        assertEquals(1, count);
        List<String> texts = decodeTxt(response.recordAt(DnsSection.ANSWER, 0));
        assertEquals(1, texts.size());
        assertEquals(txt, texts.get(0));
        if (tcpFallback) {
            assertFalse(envelope.content().isTruncated());
        } else {
            assertTrue(envelope.content().isTruncated());
        }
        assertTrue(envelope.release());
    } finally {
        dnsServer2.stop();
        if (resolver != null) {
            resolver.close();
        }
    }
}
Also used : QuestionRecord(org.apache.directory.server.dns.messages.QuestionRecord) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) InetSocketAddress(java.net.InetSocketAddress) DnsMessage(org.apache.directory.server.dns.messages.DnsMessage) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) DnsMessageEncoder(org.apache.directory.server.dns.io.encoder.DnsMessageEncoder) DatagramPacket(io.netty.channel.socket.DatagramPacket) DefaultDnsQuestion(io.netty.handler.codec.dns.DefaultDnsQuestion) AddressedEnvelope(io.netty.channel.AddressedEnvelope) InputStream(java.io.InputStream) AtomicReference(java.util.concurrent.atomic.AtomicReference) ServerSocket(java.net.ServerSocket) ByteBuffer(java.nio.ByteBuffer) IoBuffer(org.apache.mina.core.buffer.IoBuffer) RecordStore(org.apache.directory.server.dns.store.RecordStore) DnsResponse(io.netty.handler.codec.dns.DnsResponse) DnsMessageModifier(org.apache.directory.server.dns.messages.DnsMessageModifier) ServerSocket(java.net.ServerSocket) DatagramSocket(java.net.DatagramSocket) Socket(java.net.Socket) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter)

Aggregations

AddressedEnvelope (io.netty.channel.AddressedEnvelope)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 ChannelInboundHandlerAdapter (io.netty.channel.ChannelInboundHandlerAdapter)1 DatagramPacket (io.netty.channel.socket.DatagramPacket)1 DefaultDnsQuestion (io.netty.handler.codec.dns.DefaultDnsQuestion)1 DnsResponse (io.netty.handler.codec.dns.DnsResponse)1 InputStream (java.io.InputStream)1 DatagramSocket (java.net.DatagramSocket)1 InetSocketAddress (java.net.InetSocketAddress)1 ServerSocket (java.net.ServerSocket)1 Socket (java.net.Socket)1 ByteBuffer (java.nio.ByteBuffer)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 Set (java.util.Set)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 DnsMessageEncoder (org.apache.directory.server.dns.io.encoder.DnsMessageEncoder)1 DnsMessage (org.apache.directory.server.dns.messages.DnsMessage)1 DnsMessageModifier (org.apache.directory.server.dns.messages.DnsMessageModifier)1 QuestionRecord (org.apache.directory.server.dns.messages.QuestionRecord)1