Search in sources :

Example 1 with RecordStore

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

the class DnsNameResolverTest method testFollowNsRedirects.

private void testFollowNsRedirects(DnsCache cache, AuthoritativeDnsServerCache authoritativeDnsServerCache, final boolean invalidNsFirst) throws Exception {
    final String domain = "netty.io";
    final String ns1Name = "ns1." + domain;
    final String ns2Name = "ns2." + domain;
    final InetAddress expected = InetAddress.getByAddress("some.record." + domain, new byte[] { 10, 10, 10, 10 });
    // This is used to simulate a query timeout...
    final DatagramSocket socket = new DatagramSocket(new InetSocketAddress(0));
    final TestDnsServer dnsServerAuthority = new TestDnsServer(new RecordStore() {

        @Override
        public Set<ResourceRecord> getRecords(QuestionRecord question) {
            if (question.getDomainName().equals(expected.getHostName())) {
                return Collections.singleton(newARecord(expected.getHostName(), expected.getHostAddress()));
            }
            return Collections.emptySet();
        }
    });
    dnsServerAuthority.start();
    TestDnsServer redirectServer = new TestDnsServer(new HashSet<String>(asList(expected.getHostName(), ns1Name, ns2Name))) {

        @Override
        protected DnsMessage filterMessage(DnsMessage message) {
            for (QuestionRecord record : message.getQuestionRecords()) {
                if (record.getDomainName().equals(expected.getHostName())) {
                    message.getAdditionalRecords().clear();
                    message.getAnswerRecords().clear();
                    if (invalidNsFirst) {
                        message.getAuthorityRecords().add(TestDnsServer.newNsRecord(domain, ns2Name));
                        message.getAuthorityRecords().add(TestDnsServer.newNsRecord(domain, ns1Name));
                    } else {
                        message.getAuthorityRecords().add(TestDnsServer.newNsRecord(domain, ns1Name));
                        message.getAuthorityRecords().add(TestDnsServer.newNsRecord(domain, ns2Name));
                    }
                    return message;
                }
            }
            return message;
        }
    };
    redirectServer.start();
    EventLoopGroup group = new NioEventLoopGroup(1);
    final DnsNameResolver resolver = new DnsNameResolver(group.next(), new ReflectiveChannelFactory<DatagramChannel>(NioDatagramChannel.class), cache, authoritativeDnsServerCache, NoopDnsQueryLifecycleObserverFactory.INSTANCE, 2000, ResolvedAddressTypes.IPV4_ONLY, true, 10, true, 4096, false, HostsFileEntriesResolver.DEFAULT, new SingletonDnsServerAddressStreamProvider(redirectServer.localAddress()), DnsNameResolver.DEFAULT_SEARCH_DOMAINS, 0, true) {

        @Override
        InetSocketAddress newRedirectServerAddress(InetAddress server) {
            try {
                if (server.getHostName().startsWith(ns1Name)) {
                    return new InetSocketAddress(InetAddress.getByAddress(ns1Name, dnsServerAuthority.localAddress().getAddress().getAddress()), dnsServerAuthority.localAddress().getPort());
                }
                if (server.getHostName().startsWith(ns2Name)) {
                    return new InetSocketAddress(InetAddress.getByAddress(ns2Name, NetUtil.LOCALHOST.getAddress()), socket.getLocalPort());
                }
            } catch (UnknownHostException e) {
                throw new IllegalStateException(e);
            }
            return super.newRedirectServerAddress(server);
        }
    };
    try {
        List<InetAddress> resolved = resolver.resolveAll(expected.getHostName()).syncUninterruptibly().getNow();
        assertEquals(1, resolved.size());
        assertEquals(expected, resolved.get(0));
        List<InetAddress> resolved2 = resolver.resolveAll(expected.getHostName()).syncUninterruptibly().getNow();
        assertEquals(1, resolved2.size());
        assertEquals(expected, resolved2.get(0));
        if (authoritativeDnsServerCache != NoopAuthoritativeDnsServerCache.INSTANCE) {
            DnsServerAddressStream cached = authoritativeDnsServerCache.get(domain + '.');
            assertEquals(2, cached.size());
            InetSocketAddress ns1Address = InetSocketAddress.createUnresolved(ns1Name + '.', DefaultDnsServerAddressStreamProvider.DNS_PORT);
            InetSocketAddress ns2Address = InetSocketAddress.createUnresolved(ns2Name + '.', DefaultDnsServerAddressStreamProvider.DNS_PORT);
            if (invalidNsFirst) {
                assertEquals(ns2Address, cached.next());
                assertEquals(ns1Address, cached.next());
            } else {
                assertEquals(ns1Address, cached.next());
                assertEquals(ns2Address, cached.next());
            }
        }
        if (cache != NoopDnsCache.INSTANCE) {
            List<? extends DnsCacheEntry> ns1Cached = cache.get(ns1Name + '.', null);
            assertEquals(1, ns1Cached.size());
            DnsCacheEntry nsEntry = ns1Cached.get(0);
            assertNotNull(nsEntry.address());
            assertNull(nsEntry.cause());
            List<? extends DnsCacheEntry> ns2Cached = cache.get(ns2Name + '.', null);
            if (invalidNsFirst) {
                assertEquals(1, ns2Cached.size());
                DnsCacheEntry ns2Entry = ns2Cached.get(0);
                assertNotNull(ns2Entry.address());
                assertNull(ns2Entry.cause());
            } else {
                // We should not even have tried to resolve the DNS name so this should be null.
                assertNull(ns2Cached);
            }
            List<? extends DnsCacheEntry> expectedCached = cache.get(expected.getHostName(), null);
            assertEquals(1, expectedCached.size());
            DnsCacheEntry expectedEntry = expectedCached.get(0);
            assertEquals(expected, expectedEntry.address());
            assertNull(expectedEntry.cause());
        }
    } finally {
        resolver.close();
        group.shutdownGracefully(0, 0, TimeUnit.SECONDS);
        redirectServer.stop();
        dnsServerAuthority.stop();
        socket.close();
    }
}
Also used : QuestionRecord(org.apache.directory.server.dns.messages.QuestionRecord) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) UnknownHostException(java.net.UnknownHostException) InetSocketAddress(java.net.InetSocketAddress) NioDatagramChannel(io.netty.channel.socket.nio.NioDatagramChannel) DatagramChannel(io.netty.channel.socket.DatagramChannel) NioDatagramChannel(io.netty.channel.socket.nio.NioDatagramChannel) DnsMessage(org.apache.directory.server.dns.messages.DnsMessage) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) EventLoopGroup(io.netty.channel.EventLoopGroup) DatagramSocket(java.net.DatagramSocket) RecordStore(org.apache.directory.server.dns.store.RecordStore) InetAddress(java.net.InetAddress) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup)

Example 2 with RecordStore

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

the class DnsNameResolverTest method testIncludeDuplicates.

@Test
public void testIncludeDuplicates() 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>(2);
            String qName = question.getDomainName().toLowerCase();
            records.add(new TestDnsServer.TestResourceRecord(qName, RecordType.A, Collections.<String, Object>singletonMap(DnsAttribute.IP_ADDRESS.toLowerCase(), ipv4Addr)));
            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<DnsRecord> resolvedAddresses = resolver.resolveAll(new DefaultDnsQuestion(name, A)).syncUninterruptibly().getNow();
        assertEquals(2, resolvedAddresses.size());
        for (DnsRecord record : resolvedAddresses) {
            ReferenceCountUtil.release(record);
        }
    } 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) DnsRecord(io.netty.handler.codec.dns.DnsRecord) DefaultDnsQuestion(io.netty.handler.codec.dns.DefaultDnsQuestion) Test(org.junit.jupiter.api.Test)

Example 3 with RecordStore

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

the class DnsNameResolverTest method testResolvesPreferredWhenNonPreferredFirst0.

private static void testResolvesPreferredWhenNonPreferredFirst0(ResolvedAddressTypes types) throws Exception {
    final String name = "netty.com";
    // This store is non-compliant, returning records of the wrong type for a query.
    // It works since we don't verify the type of the result when resolving to deal with
    // non-compliant servers in the wild.
    List<Set<ResourceRecord>> records = new ArrayList<Set<ResourceRecord>>();
    final String ipv6Address = "0:0:0:0:0:0:1:1";
    final String ipv4Address = "1.1.1.1";
    if (types == ResolvedAddressTypes.IPV4_PREFERRED) {
        records.add(Collections.singleton(TestDnsServer.newAddressRecord(name, RecordType.AAAA, ipv6Address)));
        records.add(Collections.singleton(TestDnsServer.newAddressRecord(name, RecordType.A, ipv4Address)));
    } else {
        records.add(Collections.singleton(TestDnsServer.newAddressRecord(name, RecordType.A, ipv4Address)));
        records.add(Collections.singleton(TestDnsServer.newAddressRecord(name, RecordType.AAAA, ipv6Address)));
    }
    final Iterator<Set<ResourceRecord>> recordsIterator = records.iterator();
    RecordStore arbitrarilyOrderedStore = new RecordStore() {

        @Override
        public Set<ResourceRecord> getRecords(QuestionRecord questionRecord) {
            return recordsIterator.next();
        }
    };
    TestDnsServer nonCompliantDnsServer = new TestDnsServer(arbitrarilyOrderedStore);
    nonCompliantDnsServer.start();
    try {
        DnsNameResolver resolver = newResolver(types).maxQueriesPerResolve(2).nameServerProvider(new SingletonDnsServerAddressStreamProvider(nonCompliantDnsServer.localAddress())).build();
        InetAddress resolved = resolver.resolve("netty.com").syncUninterruptibly().getNow();
        if (types == ResolvedAddressTypes.IPV4_PREFERRED) {
            assertEquals(ipv4Address, resolved.getHostAddress());
        } else {
            assertEquals(ipv6Address, resolved.getHostAddress());
        }
        InetAddress ipv4InetAddress = InetAddress.getByAddress("netty.com", InetAddress.getByName(ipv4Address).getAddress());
        InetAddress ipv6InetAddress = InetAddress.getByAddress("netty.com", InetAddress.getByName(ipv6Address).getAddress());
        List<InetAddress> resolvedAll = resolver.resolveAll("netty.com").syncUninterruptibly().getNow();
        List<InetAddress> expected = types == ResolvedAddressTypes.IPV4_PREFERRED ? asList(ipv4InetAddress, ipv6InetAddress) : asList(ipv6InetAddress, ipv4InetAddress);
        assertEquals(expected, resolvedAll);
    } finally {
        nonCompliantDnsServer.stop();
    }
}
Also used : QuestionRecord(org.apache.directory.server.dns.messages.QuestionRecord) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) ResourceRecord(org.apache.directory.server.dns.messages.ResourceRecord) RecordStore(org.apache.directory.server.dns.store.RecordStore) InetAddress(java.net.InetAddress)

Example 4 with RecordStore

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

the class DnsNameResolverTest method testCNAMERecursiveResolveDifferentNameServersForDomains.

@Test
public void testCNAMERecursiveResolveDifferentNameServersForDomains() throws IOException {
    final String firstName = "firstname.com";
    final String secondName = "secondname.com";
    final String lastName = "lastname.com";
    final String ipv4Addr = "1.2.3.4";
    final TestDnsServer dnsServer2 = new TestDnsServer(new RecordStore() {

        @Override
        public Set<ResourceRecord> getRecords(QuestionRecord question) {
            ResourceRecordModifier rm = new ResourceRecordModifier();
            rm.setDnsClass(RecordClass.IN);
            rm.setDnsName(question.getDomainName());
            rm.setDnsTtl(100);
            if (question.getDomainName().equals(firstName)) {
                rm.setDnsType(RecordType.CNAME);
                rm.put(DnsAttribute.DOMAIN_NAME, secondName);
            } else if (question.getDomainName().equals(lastName)) {
                rm.setDnsType(question.getRecordType());
                rm.put(DnsAttribute.IP_ADDRESS, ipv4Addr);
            } else {
                return null;
            }
            return Collections.singleton(rm.getEntry());
        }
    });
    dnsServer2.start();
    final TestDnsServer dnsServer3 = new TestDnsServer(new RecordStore() {

        @Override
        public Set<ResourceRecord> getRecords(QuestionRecord question) {
            if (question.getDomainName().equals(secondName)) {
                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());
            }
            return null;
        }
    });
    dnsServer3.start();
    DnsNameResolver resolver = null;
    try {
        resolver = newResolver().resolveCache(NoopDnsCache.INSTANCE).cnameCache(NoopDnsCnameCache.INSTANCE).recursionDesired(true).maxQueriesPerResolve(16).nameServerProvider(new DnsServerAddressStreamProvider() {

            @Override
            public DnsServerAddressStream nameServerAddressStream(String hostname) {
                if (hostname.equals(secondName + '.')) {
                    return DnsServerAddresses.singleton(dnsServer3.localAddress()).stream();
                }
                return DnsServerAddresses.singleton(dnsServer2.localAddress()).stream();
            }
        }).resolvedAddressTypes(ResolvedAddressTypes.IPV4_PREFERRED).build();
        assertResolvedAddress(resolver.resolve(firstName).syncUninterruptibly().getNow(), ipv4Addr, firstName);
    } 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) RecordStore(org.apache.directory.server.dns.store.RecordStore) ResourceRecordModifier(org.apache.directory.server.dns.messages.ResourceRecordModifier) Test(org.junit.jupiter.api.Test)

Example 5 with RecordStore

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

the class DnsNameResolverTest method testCNameCached.

@Test
public void testCNameCached() throws Exception {
    final Map<String, String> cache = new ConcurrentHashMap<String, String>();
    final AtomicInteger cnameQueries = new AtomicInteger();
    final AtomicInteger aQueries = new AtomicInteger();
    TestDnsServer dnsServer2 = new TestDnsServer(new RecordStore() {

        @Override
        public Set<ResourceRecord> getRecords(QuestionRecord question) {
            if ("cname.netty.io".equals(question.getDomainName())) {
                aQueries.incrementAndGet();
                return Collections.<ResourceRecord>singleton(new TestDnsServer.TestResourceRecord(question.getDomainName(), RecordType.A, Collections.<String, Object>singletonMap(DnsAttribute.IP_ADDRESS.toLowerCase(), "10.0.0.99")));
            }
            if ("x.netty.io".equals(question.getDomainName())) {
                cnameQueries.incrementAndGet();
                return Collections.<ResourceRecord>singleton(new TestDnsServer.TestResourceRecord(question.getDomainName(), RecordType.CNAME, Collections.<String, Object>singletonMap(DnsAttribute.DOMAIN_NAME.toLowerCase(), "cname.netty.io")));
            }
            if ("y.netty.io".equals(question.getDomainName())) {
                cnameQueries.incrementAndGet();
                return Collections.<ResourceRecord>singleton(new TestDnsServer.TestResourceRecord(question.getDomainName(), RecordType.CNAME, Collections.<String, Object>singletonMap(DnsAttribute.DOMAIN_NAME.toLowerCase(), "x.netty.io")));
            }
            return Collections.emptySet();
        }
    });
    dnsServer2.start();
    DnsNameResolver resolver = null;
    try {
        DnsNameResolverBuilder builder = newResolver().recursionDesired(true).resolvedAddressTypes(ResolvedAddressTypes.IPV4_ONLY).maxQueriesPerResolve(16).nameServerProvider(new SingletonDnsServerAddressStreamProvider(dnsServer2.localAddress())).resolveCache(NoopDnsCache.INSTANCE).cnameCache(new DnsCnameCache() {

            @Override
            public String get(String hostname) {
                assertTrue(hostname.endsWith("."), hostname);
                return cache.get(hostname);
            }

            @Override
            public void cache(String hostname, String cname, long originalTtl, EventLoop loop) {
                assertTrue(hostname.endsWith("."), hostname);
                cache.put(hostname, cname);
            }

            @Override
            public void clear() {
            // NOOP
            }

            @Override
            public boolean clear(String hostname) {
                return false;
            }
        });
        resolver = builder.build();
        List<InetAddress> resolvedAddresses = resolver.resolveAll("x.netty.io").syncUninterruptibly().getNow();
        assertEquals(1, resolvedAddresses.size());
        assertTrue(resolvedAddresses.contains(InetAddress.getByAddress(new byte[] { 10, 0, 0, 99 })));
        assertEquals("cname.netty.io.", cache.get("x.netty.io."));
        assertEquals(1, cnameQueries.get());
        assertEquals(1, aQueries.get());
        resolvedAddresses = resolver.resolveAll("x.netty.io").syncUninterruptibly().getNow();
        assertEquals(1, resolvedAddresses.size());
        assertTrue(resolvedAddresses.contains(InetAddress.getByAddress(new byte[] { 10, 0, 0, 99 })));
        // Should not have queried for the CNAME again.
        assertEquals(1, cnameQueries.get());
        assertEquals(2, aQueries.get());
        resolvedAddresses = resolver.resolveAll("y.netty.io").syncUninterruptibly().getNow();
        assertEquals(1, resolvedAddresses.size());
        assertTrue(resolvedAddresses.contains(InetAddress.getByAddress(new byte[] { 10, 0, 0, 99 })));
        assertEquals("x.netty.io.", cache.get("y.netty.io."));
        // Will only query for one CNAME
        assertEquals(2, cnameQueries.get());
        assertEquals(3, aQueries.get());
        resolvedAddresses = resolver.resolveAll("y.netty.io").syncUninterruptibly().getNow();
        assertEquals(1, resolvedAddresses.size());
        assertTrue(resolvedAddresses.contains(InetAddress.getByAddress(new byte[] { 10, 0, 0, 99 })));
        // Should not have queried for the CNAME again.
        assertEquals(2, cnameQueries.get());
        assertEquals(4, aQueries.get());
    } 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) EventLoop(io.netty.channel.EventLoop) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RecordStore(org.apache.directory.server.dns.store.RecordStore) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) InetAddress(java.net.InetAddress) Test(org.junit.jupiter.api.Test)

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