Search in sources :

Example 1 with DnsRecord

use of io.netty.handler.codec.dns.DnsRecord in project netty by netty.

the class DnsNameResolverTest method testQueryMx.

@Test
public void testQueryMx() throws Exception {
    DnsNameResolver resolver = newResolver().build();
    try {
        assertThat(resolver.isRecursionDesired(), is(true));
        Map<String, Future<AddressedEnvelope<DnsResponse, InetSocketAddress>>> futures = new LinkedHashMap<String, Future<AddressedEnvelope<DnsResponse, InetSocketAddress>>>();
        for (String name : DOMAINS) {
            if (EXCLUSIONS_QUERY_MX.contains(name)) {
                continue;
            }
            queryMx(resolver, futures, name);
        }
        for (Entry<String, Future<AddressedEnvelope<DnsResponse, InetSocketAddress>>> e : futures.entrySet()) {
            String hostname = e.getKey();
            Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> f = e.getValue().awaitUninterruptibly();
            DnsResponse response = f.getNow().content();
            assertThat(response.code(), is(DnsResponseCode.NOERROR));
            final int answerCount = response.count(DnsSection.ANSWER);
            final List<DnsRecord> mxList = new ArrayList<DnsRecord>(answerCount);
            for (int i = 0; i < answerCount; i++) {
                final DnsRecord r = response.recordAt(DnsSection.ANSWER, i);
                if (r.type() == DnsRecordType.MX) {
                    mxList.add(r);
                }
            }
            assertThat(mxList.size(), is(greaterThan(0)));
            StringBuilder buf = new StringBuilder();
            for (DnsRecord r : mxList) {
                ByteBuf recordContent = ((ByteBufHolder) r).content();
                buf.append(StringUtil.NEWLINE);
                buf.append('\t');
                buf.append(r.name());
                buf.append(' ');
                buf.append(r.type().name());
                buf.append(' ');
                buf.append(recordContent.readUnsignedShort());
                buf.append(' ');
                buf.append(DnsNameResolverContext.decodeDomainName(recordContent));
            }
            logger.info("{} has the following MX records:{}", hostname, buf);
            response.release();
        }
    } finally {
        resolver.close();
    }
}
Also used : AddressedEnvelope(io.netty.channel.AddressedEnvelope) InetSocketAddress(java.net.InetSocketAddress) ArrayList(java.util.ArrayList) ByteBuf(io.netty.buffer.ByteBuf) LinkedHashMap(java.util.LinkedHashMap) DnsResponse(io.netty.handler.codec.dns.DnsResponse) Future(io.netty.util.concurrent.Future) ByteBufHolder(io.netty.buffer.ByteBufHolder) DnsRecord(io.netty.handler.codec.dns.DnsRecord) Test(org.junit.Test)

Example 2 with DnsRecord

use of io.netty.handler.codec.dns.DnsRecord in project netty by netty.

the class DnsNameResolver method toArray.

private static DnsRecord[] toArray(Iterable<DnsRecord> additionals, boolean validateType) {
    checkNotNull(additionals, "additionals");
    if (additionals instanceof Collection) {
        Collection<DnsRecord> records = (Collection<DnsRecord>) additionals;
        for (DnsRecord r : additionals) {
            validateAdditional(r, validateType);
        }
        return records.toArray(new DnsRecord[records.size()]);
    }
    Iterator<DnsRecord> additionalsIt = additionals.iterator();
    if (!additionalsIt.hasNext()) {
        return EMPTY_ADDITIONALS;
    }
    List<DnsRecord> records = new ArrayList<DnsRecord>();
    do {
        DnsRecord r = additionalsIt.next();
        validateAdditional(r, validateType);
        records.add(r);
    } while (additionalsIt.hasNext());
    return records.toArray(new DnsRecord[records.size()]);
}
Also used : ArrayList(java.util.ArrayList) Collection(java.util.Collection) DnsRecord(io.netty.handler.codec.dns.DnsRecord)

Example 3 with DnsRecord

use of io.netty.handler.codec.dns.DnsRecord in project netty by netty.

the class DnsNameResolverContext method onResponseAorAAAA.

private void onResponseAorAAAA(DnsRecordType qType, DnsQuestion question, AddressedEnvelope<DnsResponse, InetSocketAddress> envelope, Promise<T> promise) {
    // We often get a bunch of CNAMES as well when we asked for A/AAAA.
    final DnsResponse response = envelope.content();
    final Map<String, String> cnames = buildAliasMap(response);
    final int answerCount = response.count(DnsSection.ANSWER);
    boolean found = false;
    for (int i = 0; i < answerCount; i++) {
        final DnsRecord r = response.recordAt(DnsSection.ANSWER, i);
        final DnsRecordType type = r.type();
        if (type != DnsRecordType.A && type != DnsRecordType.AAAA) {
            continue;
        }
        final String questionName = question.name().toLowerCase(Locale.US);
        final String recordName = r.name().toLowerCase(Locale.US);
        // Make sure the record is for the questioned domain.
        if (!recordName.equals(questionName)) {
            // Even if the record's name is not exactly same, it might be an alias defined in the CNAME records.
            String resolved = questionName;
            do {
                resolved = cnames.get(resolved);
                if (recordName.equals(resolved)) {
                    break;
                }
            } while (resolved != null);
            if (resolved == null) {
                continue;
            }
        }
        InetAddress resolved = parseAddress(r, hostname);
        if (resolved == null) {
            continue;
        }
        if (resolvedEntries == null) {
            resolvedEntries = new ArrayList<DnsCacheEntry>(8);
        }
        final DnsCacheEntry e = new DnsCacheEntry(hostname, resolved);
        resolveCache.cache(hostname, additionals, resolved, r.timeToLive(), parent.ch.eventLoop());
        resolvedEntries.add(e);
        found = true;
    // Note that we do not break from the loop here, so we decode/cache all A/AAAA records.
    }
    if (found) {
        return;
    }
    if (traceEnabled) {
        addTrace(envelope.sender(), "no matching " + qType + " record found");
    }
    // We aked for A/AAAA but we got only CNAME.
    if (!cnames.isEmpty()) {
        onResponseCNAME(question, envelope, cnames, false, promise);
    }
}
Also used : DnsResponse(io.netty.handler.codec.dns.DnsResponse) DnsRecordType(io.netty.handler.codec.dns.DnsRecordType) DnsRecord(io.netty.handler.codec.dns.DnsRecord) InetAddress(java.net.InetAddress)

Example 4 with DnsRecord

use of io.netty.handler.codec.dns.DnsRecord in project netty by netty.

the class DnsNameResolverContext method handleRedirect.

/**
     * Handle redirects if needed and returns {@code true} if there was a redirect handled. If {@code true} is returned
     * this method took ownership of the {@code promise} otherwise {@code false} is returned.
     */
private boolean handleRedirect(DnsQuestion question, AddressedEnvelope<DnsResponse, InetSocketAddress> envelope, Promise<T> promise) {
    final DnsResponse res = envelope.content();
    // Check if we have answers, if not this may be an non authority NS and so redirects must be handled.
    if (res.count(DnsSection.ANSWER) == 0) {
        AuthoritativeNameServerList serverNames = extractAuthoritativeNameServers(question.name(), res);
        if (serverNames != null) {
            List<InetSocketAddress> nameServers = new ArrayList<InetSocketAddress>(serverNames.size());
            int additionalCount = res.count(DnsSection.ADDITIONAL);
            for (int i = 0; i < additionalCount; i++) {
                final DnsRecord r = res.recordAt(DnsSection.ADDITIONAL, i);
                if ((r.type() == DnsRecordType.A && !parent.supportsARecords()) || r.type() == DnsRecordType.AAAA && !parent.supportsAAAARecords()) {
                    continue;
                }
                final String recordName = r.name();
                AuthoritativeNameServer authoritativeNameServer = serverNames.remove(recordName);
                if (authoritativeNameServer == null) {
                    // Not a server we are interested in.
                    continue;
                }
                InetAddress resolved = parseAddress(r, recordName);
                if (resolved == null) {
                    // Could not parse it, move to the next.
                    continue;
                }
                nameServers.add(new InetSocketAddress(resolved, parent.dnsRedirectPort(resolved)));
                addNameServerToCache(authoritativeNameServer, resolved, r.timeToLive());
            }
            if (nameServers.isEmpty()) {
                promise.tryFailure(new UnknownHostException("Unable to find correct name server for " + hostname));
            } else {
                // Shuffle as we want to re-distribute the load across name servers.
                query(DnsServerAddresses.shuffled(nameServers).stream(), question, promise);
            }
            return true;
        }
    }
    return false;
}
Also used : UnknownHostException(java.net.UnknownHostException) InetSocketAddress(java.net.InetSocketAddress) DnsResponse(io.netty.handler.codec.dns.DnsResponse) ArrayList(java.util.ArrayList) DnsRecord(io.netty.handler.codec.dns.DnsRecord) InetAddress(java.net.InetAddress)

Example 5 with DnsRecord

use of io.netty.handler.codec.dns.DnsRecord in project netty by netty.

the class DnsQueryContext method query.

void query() {
    final DnsQuestion question = question();
    final InetSocketAddress nameServerAddr = nameServerAddr();
    final DatagramDnsQuery query = new DatagramDnsQuery(null, nameServerAddr, id);
    query.setRecursionDesired(recursionDesired);
    query.addRecord(DnsSection.QUESTION, question);
    for (DnsRecord record : additionals) {
        query.addRecord(DnsSection.ADDITIONAL, record);
    }
    if (optResource != null) {
        query.addRecord(DnsSection.ADDITIONAL, optResource);
    }
    if (logger.isDebugEnabled()) {
        logger.debug("{} WRITE: [{}: {}], {}", parent.ch, id, nameServerAddr, question);
    }
    sendQuery(query);
}
Also used : InetSocketAddress(java.net.InetSocketAddress) DatagramDnsQuery(io.netty.handler.codec.dns.DatagramDnsQuery) DnsQuestion(io.netty.handler.codec.dns.DnsQuestion) DnsRecord(io.netty.handler.codec.dns.DnsRecord)

Aggregations

DnsRecord (io.netty.handler.codec.dns.DnsRecord)8 DnsRecordType (io.netty.handler.codec.dns.DnsRecordType)4 DnsResponse (io.netty.handler.codec.dns.DnsResponse)4 ArrayList (java.util.ArrayList)4 InetSocketAddress (java.net.InetSocketAddress)3 UnknownHostException (java.net.UnknownHostException)3 ByteBuf (io.netty.buffer.ByteBuf)2 ByteBufHolder (io.netty.buffer.ByteBufHolder)2 DatagramDnsQuery (io.netty.handler.codec.dns.DatagramDnsQuery)2 InetAddress (java.net.InetAddress)2 AddressedEnvelope (io.netty.channel.AddressedEnvelope)1 ChannelFuture (io.netty.channel.ChannelFuture)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 DecoderException (io.netty.handler.codec.DecoderException)1 DefaultDnsQuestion (io.netty.handler.codec.dns.DefaultDnsQuestion)1 DnsQuestion (io.netty.handler.codec.dns.DnsQuestion)1 DnsRawRecord (io.netty.handler.codec.dns.DnsRawRecord)1 Future (io.netty.util.concurrent.Future)1 DnsException (io.vertx.core.dns.DnsException)1 DnsResponseCode (io.vertx.core.dns.DnsResponseCode)1