Search in sources :

Example 16 with RecordStore

use of org.apache.directory.server.dns.store.RecordStore in project netty by netty.

the class DnsNameResolverTest method testCNAMERecursiveResolveMultipleNameServers.

private static void testCNAMERecursiveResolveMultipleNameServers(boolean ipv4Preferred) throws IOException {
    final String firstName = "firstname.nettyfoo.com";
    final String lastName = "lastname.nettybar.com";
    final String ipv4Addr = "1.2.3.4";
    final String ipv6Addr = "::1";
    final AtomicBoolean hitServer2 = new AtomicBoolean();
    final TestDnsServer dnsServer2 = new TestDnsServer(new RecordStore() {

        @Override
        public Set<ResourceRecord> getRecords(QuestionRecord question) throws DnsException {
            hitServer2.set(true);
            if (question.getDomainName().equals(firstName)) {
                ResourceRecordModifier rm = new ResourceRecordModifier();
                rm.setDnsClass(RecordClass.IN);
                rm.setDnsName(question.getDomainName());
                rm.setDnsTtl(100);
                rm.setDnsType(RecordType.CNAME);
                rm.put(DnsAttribute.DOMAIN_NAME, lastName);
                return Collections.singleton(rm.getEntry());
            } else {
                throw new DnsException(ResponseCode.REFUSED);
            }
        }
    });
    final TestDnsServer dnsServer3 = new TestDnsServer(new RecordStore() {

        @Override
        public Set<ResourceRecord> getRecords(QuestionRecord question) throws DnsException {
            if (question.getDomainName().equals(lastName)) {
                ResourceRecordModifier rm = new ResourceRecordModifier();
                rm.setDnsClass(RecordClass.IN);
                rm.setDnsName(question.getDomainName());
                rm.setDnsTtl(100);
                rm.setDnsType(question.getRecordType());
                switch(question.getRecordType()) {
                    case A:
                        rm.put(DnsAttribute.IP_ADDRESS, ipv4Addr);
                        break;
                    case AAAA:
                        rm.put(DnsAttribute.IP_ADDRESS, ipv6Addr);
                        break;
                    default:
                        return null;
                }
                return Collections.singleton(rm.getEntry());
            } else {
                throw new DnsException(ResponseCode.REFUSED);
            }
        }
    });
    dnsServer2.start();
    dnsServer3.start();
    DnsNameResolver resolver = null;
    try {
        AuthoritativeDnsServerCache nsCache = new DefaultAuthoritativeDnsServerCache();
        // What we want to test is the following:
        // 1. Do a DNS query.
        // 2. CNAME is returned, we want to lookup that CNAME on multiple DNS servers
        // 3. The first DNS server should fail
        // 4. The second DNS server should succeed
        // This verifies that we do in fact follow multiple DNS servers in the CNAME resolution.
        // The DnsCache is used for the name server cache, but doesn't provide a InetSocketAddress (only InetAddress
        // so no port), so we only specify the name server in the cache, and then specify both name servers in the
        // fallback name server provider.
        nsCache.cache("nettyfoo.com.", dnsServer2.localAddress(), 10000, group.next());
        resolver = new DnsNameResolver(group.next(), new ReflectiveChannelFactory<DatagramChannel>(NioDatagramChannel.class), NoopDnsCache.INSTANCE, nsCache, NoopDnsQueryLifecycleObserverFactory.INSTANCE, 3000, ipv4Preferred ? ResolvedAddressTypes.IPV4_ONLY : ResolvedAddressTypes.IPV6_ONLY, true, 10, true, 4096, false, HostsFileEntriesResolver.DEFAULT, new SequentialDnsServerAddressStreamProvider(dnsServer2.localAddress(), dnsServer3.localAddress()), DnsNameResolver.DEFAULT_SEARCH_DOMAINS, 0, true) {

            @Override
            InetSocketAddress newRedirectServerAddress(InetAddress server) {
                int port = hitServer2.get() ? dnsServer3.localAddress().getPort() : dnsServer2.localAddress().getPort();
                return new InetSocketAddress(server, port);
            }
        };
        InetAddress resolvedAddress = resolver.resolve(firstName).syncUninterruptibly().getNow();
        if (ipv4Preferred) {
            assertEquals(ipv4Addr, resolvedAddress.getHostAddress());
        } else {
            assertEquals(ipv6Addr, NetUtil.toAddressString(resolvedAddress));
        }
        assertEquals(firstName, resolvedAddress.getHostName());
    } finally {
        dnsServer2.stop();
        dnsServer3.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) ResourceRecordModifier(org.apache.directory.server.dns.messages.ResourceRecordModifier) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) DnsException(org.apache.directory.server.dns.DnsException) RecordStore(org.apache.directory.server.dns.store.RecordStore) ReflectiveChannelFactory(io.netty.channel.ReflectiveChannelFactory) InetAddress(java.net.InetAddress)

Example 17 with RecordStore

use of org.apache.directory.server.dns.store.RecordStore in project netty by netty.

the class DnsNameResolverTest method testNotIncludeDuplicates.

@Test
public void testNotIncludeDuplicates() throws IOException {
    final String name = "netty.io";
    final String ipv4Addr = "1.2.3.4";
    TestDnsServer dnsServer2 = new TestDnsServer(new RecordStore() {

        @Override
        public Set<ResourceRecord> getRecords(QuestionRecord question) {
            Set<ResourceRecord> records = new LinkedHashSet<ResourceRecord>(4);
            String qName = question.getDomainName().toLowerCase();
            if (qName.equals(name)) {
                records.add(new TestDnsServer.TestResourceRecord(qName, RecordType.CNAME, Collections.<String, Object>singletonMap(DnsAttribute.DOMAIN_NAME.toLowerCase(), "cname.netty.io")));
                records.add(new TestDnsServer.TestResourceRecord(qName, RecordType.A, Collections.<String, Object>singletonMap(DnsAttribute.IP_ADDRESS.toLowerCase(), ipv4Addr)));
            } else {
                records.add(new TestDnsServer.TestResourceRecord(qName, RecordType.A, Collections.<String, Object>singletonMap(DnsAttribute.IP_ADDRESS.toLowerCase(), ipv4Addr)));
            }
            return records;
        }
    });
    dnsServer2.start();
    DnsNameResolver resolver = null;
    try {
        DnsNameResolverBuilder builder = newResolver().recursionDesired(true).maxQueriesPerResolve(16).nameServerProvider(new SingletonDnsServerAddressStreamProvider(dnsServer2.localAddress()));
        builder.resolvedAddressTypes(ResolvedAddressTypes.IPV4_ONLY);
        resolver = builder.build();
        List<InetAddress> resolvedAddresses = resolver.resolveAll(name).syncUninterruptibly().getNow();
        assertEquals(Collections.singletonList(InetAddress.getByAddress(name, new byte[] { 1, 2, 3, 4 })), resolvedAddresses);
    } 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) ResourceRecord(org.apache.directory.server.dns.messages.ResourceRecord) RecordStore(org.apache.directory.server.dns.store.RecordStore) InetAddress(java.net.InetAddress) Test(org.junit.jupiter.api.Test)

Example 18 with RecordStore

use of org.apache.directory.server.dns.store.RecordStore in project netty by netty.

the class DnsNameResolverTest method testAllNameServers.

@Test
public void testAllNameServers() throws IOException {
    final String domain = "netty.io";
    final String ipv4Addr = "1.2.3.4";
    final AtomicInteger server2Counter = new AtomicInteger();
    final TestDnsServer dnsServer2 = new TestDnsServer(new RecordStore() {

        @Override
        public Set<ResourceRecord> getRecords(QuestionRecord question) {
            server2Counter.incrementAndGet();
            ResourceRecordModifier rm = new ResourceRecordModifier();
            rm.setDnsClass(RecordClass.IN);
            rm.setDnsName(question.getDomainName());
            rm.setDnsTtl(100);
            rm.setDnsType(question.getRecordType());
            rm.put(DnsAttribute.IP_ADDRESS, ipv4Addr);
            return Collections.singleton(rm.getEntry());
        }
    });
    dnsServer2.start();
    final AtomicInteger server3Counter = new AtomicInteger();
    final TestDnsServer dnsServer3 = new TestDnsServer(new RecordStore() {

        @Override
        public Set<ResourceRecord> getRecords(QuestionRecord question) {
            server3Counter.incrementAndGet();
            ResourceRecordModifier rm = new ResourceRecordModifier();
            rm.setDnsClass(RecordClass.IN);
            rm.setDnsName(question.getDomainName());
            rm.setDnsTtl(100);
            rm.setDnsType(question.getRecordType());
            rm.put(DnsAttribute.IP_ADDRESS, ipv4Addr);
            return Collections.singleton(rm.getEntry());
        }
    });
    dnsServer3.start();
    DnsNameResolver resolver = null;
    try {
        resolver = newResolver().resolveCache(NoopDnsCache.INSTANCE).cnameCache(NoopDnsCnameCache.INSTANCE).recursionDesired(true).maxQueriesPerResolve(16).nameServerProvider(new DnsServerAddressStreamProvider() {

            private final DnsServerAddresses addresses = DnsServerAddresses.rotational(dnsServer2.localAddress(), dnsServer3.localAddress());

            @Override
            public DnsServerAddressStream nameServerAddressStream(String hostname) {
                return addresses.stream();
            }
        }).resolvedAddressTypes(ResolvedAddressTypes.IPV4_ONLY).build();
        assertResolvedAddress(resolver.resolve(domain).syncUninterruptibly().getNow(), ipv4Addr, domain);
        assertEquals(1, server2Counter.get());
        assertEquals(0, server3Counter.get());
        assertResolvedAddress(resolver.resolve(domain).syncUninterruptibly().getNow(), ipv4Addr, domain);
        assertEquals(1, server2Counter.get());
        assertEquals(1, server3Counter.get());
        assertResolvedAddress(resolver.resolve(domain).syncUninterruptibly().getNow(), ipv4Addr, domain);
        assertEquals(2, server2Counter.get());
        assertEquals(1, server3Counter.get());
        assertResolvedAddress(resolver.resolve(domain).syncUninterruptibly().getNow(), ipv4Addr, domain);
        assertEquals(2, server2Counter.get());
        assertEquals(2, server3Counter.get());
    } finally {
        dnsServer2.stop();
        dnsServer3.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) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RecordStore(org.apache.directory.server.dns.store.RecordStore) ResourceRecordModifier(org.apache.directory.server.dns.messages.ResourceRecordModifier) Test(org.junit.jupiter.api.Test)

Example 19 with RecordStore

use of org.apache.directory.server.dns.store.RecordStore 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

QuestionRecord (org.apache.directory.server.dns.messages.QuestionRecord)19 RecordStore (org.apache.directory.server.dns.store.RecordStore)19 HashSet (java.util.HashSet)18 LinkedHashSet (java.util.LinkedHashSet)18 Set (java.util.Set)18 Test (org.junit.jupiter.api.Test)12 InetAddress (java.net.InetAddress)10 ResourceRecord (org.apache.directory.server.dns.messages.ResourceRecord)10 DefaultDnsQuestion (io.netty.handler.codec.dns.DefaultDnsQuestion)5 ResourceRecordModifier (org.apache.directory.server.dns.messages.ResourceRecordModifier)5 InetSocketAddress (java.net.InetSocketAddress)4 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)4 HashMap (java.util.HashMap)3 LinkedHashMap (java.util.LinkedHashMap)3 Map (java.util.Map)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 DnsException (org.apache.directory.server.dns.DnsException)3 DnsMessage (org.apache.directory.server.dns.messages.DnsMessage)3 DnsResponse (io.netty.handler.codec.dns.DnsResponse)2 DatagramSocket (java.net.DatagramSocket)2