io.netty.handler.codec.dns.DnsResponse Java Examples

The following examples show how to use io.netty.handler.codec.dns.DnsResponse. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DnsNameResolver.java    From netty-4.1.22 with Apache License 2.0 6 votes vote down vote up
final Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query0(
        InetSocketAddress nameServerAddr, DnsQuestion question,
        DnsRecord[] additionals,
        ChannelPromise writePromise,
        Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {
    assert !writePromise.isVoid();

    final Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> castPromise = cast(
            checkNotNull(promise, "promise"));
    try {
        new DnsQueryContext(this, nameServerAddr, question, additionals, castPromise).query(writePromise);
        return castPromise;
    } catch (Exception e) {
        return castPromise.setFailure(e);
    }
}
 
Example #2
Source File: DnsQueryContext.java    From netty-4.1.22 with Apache License 2.0 6 votes vote down vote up
private void setSuccess(AddressedEnvelope<? extends DnsResponse, InetSocketAddress> envelope) {
    parent.queryContextManager.remove(nameServerAddr(), id);

    // Cancel the timeout task.
    final ScheduledFuture<?> timeoutFuture = this.timeoutFuture;
    if (timeoutFuture != null) {
        timeoutFuture.cancel(false);
    }

    Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise = this.promise;
    if (promise.setUncancellable()) {
        @SuppressWarnings("unchecked")
        AddressedEnvelope<DnsResponse, InetSocketAddress> castResponse =
                (AddressedEnvelope<DnsResponse, InetSocketAddress>) envelope.retain();
        if (!promise.trySuccess(castResponse)) {
            // We failed to notify the promise as it was failed before, thus we need to release the envelope
            envelope.release();
        }
    }
}
 
Example #3
Source File: DnsQueryContext.java    From netty-4.1.22 with Apache License 2.0 6 votes vote down vote up
DnsQueryContext(DnsNameResolver parent,
                InetSocketAddress nameServerAddr,
                DnsQuestion question,
                DnsRecord[] additionals,
                Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise) {

    this.parent = checkNotNull(parent, "parent");
    this.nameServerAddr = checkNotNull(nameServerAddr, "nameServerAddr");
    this.question = checkNotNull(question, "question");
    this.additionals = checkNotNull(additionals, "additionals");
    this.promise = checkNotNull(promise, "promise");
    recursionDesired = parent.isRecursionDesired();
    id = parent.queryContextManager.add(this);

    if (parent.isOptResourceEnabled()) {
        optResource = new AbstractDnsOptPseudoRrRecord(parent.maxPayloadSize(), 0, 0) {
            // We may want to remove this in the future and let the user just specify the opt record in the query.
        };
    } else {
        optResource = null;
    }
}
 
Example #4
Source File: TestDnsServer.java    From armeria with Apache License 2.0 6 votes vote down vote up
public TestDnsServer(Map<DnsQuestion, DnsResponse> responses,
                     @Nullable ChannelInboundHandlerAdapter beforeDnsServerHandler) {
    this.responses = ImmutableMap.copyOf(responses);

    final Bootstrap b = new Bootstrap();
    b.channel(TransportType.datagramChannelType(CommonPools.workerGroup()));
    b.group(CommonPools.workerGroup());
    b.handler(new ChannelInitializer() {
        @Override
        protected void initChannel(Channel ch) throws Exception {
            final ChannelPipeline p = ch.pipeline();
            p.addLast(new DatagramDnsQueryDecoder());
            p.addLast(new DatagramDnsResponseEncoder());
            if (beforeDnsServerHandler != null) {
                p.addLast(beforeDnsServerHandler);
            }
            p.addLast(new DnsServerHandler());
        }
    });

    channel = b.bind(NetUtil.LOCALHOST, 0).syncUninterruptibly().channel();
}
 
Example #5
Source File: DnsNameResolverContext.java    From netty-4.1.22 with Apache License 2.0 6 votes vote down vote up
private static Map<String, String> buildAliasMap(DnsResponse response) {
    final int answerCount = response.count(DnsSection.ANSWER);
    Map<String, String> cnames = null;
    for (int i = 0; i < answerCount; i ++) {
        final DnsRecord r = response.recordAt(DnsSection.ANSWER, i);
        final DnsRecordType type = r.type();
        if (type != DnsRecordType.CNAME) {
            continue;
        }

        if (!(r instanceof DnsRawRecord)) {
            continue;
        }

        final ByteBuf recordContent = ((ByteBufHolder) r).content();
        final String domainName = decodeDomainName(recordContent);
        if (domainName == null) {
            continue;
        }

        if (cnames == null) {
            cnames = new HashMap<String, String>(min(8, answerCount));
        }

        cnames.put(r.name().toLowerCase(Locale.US), domainName.toLowerCase(Locale.US));
    }

    return cnames != null? cnames : Collections.<String, String>emptyMap();
}
 
Example #6
Source File: DnsNameResolverContext.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
private void onResponseCNAME(
        DnsQuestion question, AddressedEnvelope<DnsResponse, InetSocketAddress> response,
        Map<String, String> cnames, final DnsQueryLifecycleObserver queryLifecycleObserver,
        Promise<T> promise) {

    // Resolve the host name in the question into the real host name.
    final String name = question.name().toLowerCase(Locale.US);
    String resolved = name;
    boolean found = false;
    while (!cnames.isEmpty()) { // Do not attempt to call Map.remove() when the Map is empty
                                // because it can be Collections.emptyMap()
                                // whose remove() throws a UnsupportedOperationException.
        final String next = cnames.remove(resolved);
        if (next != null) {
            found = true;
            resolved = next;
        } else {
            break;
        }
    }

    if (found) {
        followCname(question, resolved, queryLifecycleObserver, promise);
    } else {
        queryLifecycleObserver.queryFailed(CNAME_NOT_FOUND_QUERY_FAILED_EXCEPTION);
    }
}
 
Example #7
Source File: DnsNameResolver.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
/**
 * Sends a DNS query with the specified question with additional records using the specified name server list.
 */
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
        InetSocketAddress nameServerAddr, DnsQuestion question,
        Iterable<DnsRecord> additionals,
        Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {

    return query0(nameServerAddr, question, toArray(additionals, false), promise);
}
 
Example #8
Source File: DnsNameResolver.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
/**
 * Sends a DNS query with the specified question using the specified name server list.
 */
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
        InetSocketAddress nameServerAddr, DnsQuestion question,
        Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {

    return query0(nameServerAddr, question, EMPTY_ADDITIONALS, promise);
}
 
Example #9
Source File: DnsNameResolver.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
/**
 * Sends a DNS query with the specified question with additional records using the specified name server list.
 */
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
        InetSocketAddress nameServerAddr, DnsQuestion question, Iterable<DnsRecord> additionals) {

    return query0(nameServerAddr, question, toArray(additionals, false),
            ch.eventLoop().<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>>newPromise());
}
 
Example #10
Source File: DnsNameResolver.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
/**
 * Sends a DNS query with the specified question using the specified name server list.
 */
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
        InetSocketAddress nameServerAddr, DnsQuestion question) {

    return query0(nameServerAddr, question, EMPTY_ADDITIONALS,
            ch.eventLoop().<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>>newPromise());
}
 
Example #11
Source File: DnsNameResolverContext.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the {@code {@link AuthoritativeNameServerList} which were included in {@link DnsSection#AUTHORITY}
 * or {@code null} if non are found.
 */
private static AuthoritativeNameServerList extractAuthoritativeNameServers(String questionName, DnsResponse res) {
    int authorityCount = res.count(DnsSection.AUTHORITY);
    if (authorityCount == 0) {
        return null;
    }

    AuthoritativeNameServerList serverNames = new AuthoritativeNameServerList(questionName);
    for (int i = 0; i < authorityCount; i++) {
        serverNames.add(res.recordAt(DnsSection.AUTHORITY, i));
    }
    return serverNames;
}
 
Example #12
Source File: DnsNameResolverContext.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
void onResponse(final DnsServerAddressStream nameServerAddrStream, final int nameServerAddrStreamIndex,
                final DnsQuestion question, AddressedEnvelope<DnsResponse, InetSocketAddress> envelope,
                final DnsQueryLifecycleObserver queryLifecycleObserver,
                Promise<T> promise) {
    try {
        final DnsResponse res = envelope.content();
        final DnsResponseCode code = res.code();
        if (code == DnsResponseCode.NOERROR) {
            if (handleRedirect(question, envelope, queryLifecycleObserver, promise)) {
                // Was a redirect so return here as everything else is handled in handleRedirect(...)
                return;
            }
            final DnsRecordType type = question.type();

            if (type == DnsRecordType.A || type == DnsRecordType.AAAA) {
                onResponseAorAAAA(type, question, envelope, queryLifecycleObserver, promise);
            } else if (type == DnsRecordType.CNAME) {
                onResponseCNAME(question, envelope, queryLifecycleObserver, promise);
            } else {
                queryLifecycleObserver.queryFailed(UNRECOGNIZED_TYPE_QUERY_FAILED_EXCEPTION);
            }
            return;
        }

        // Retry with the next server if the server did not tell us that the domain does not exist.
        if (code != DnsResponseCode.NXDOMAIN) {
            query(nameServerAddrStream, nameServerAddrStreamIndex + 1, question,
                  queryLifecycleObserver.queryNoAnswer(code), promise, null);
        } else {
            queryLifecycleObserver.queryFailed(NXDOMAIN_QUERY_FAILED_EXCEPTION);
        }
    } finally {
        ReferenceCountUtil.safeRelease(envelope);
    }
}
 
Example #13
Source File: TestDnsServer.java    From armeria with Apache License 2.0 5 votes vote down vote up
@Override
public void close() {
    if (!channel.isOpen()) {
        return;
    }

    channel.close().syncUninterruptibly();
    responses.values().forEach(DnsResponse::release);
}
 
Example #14
Source File: DnsQueryContext.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
void finish(AddressedEnvelope<? extends DnsResponse, InetSocketAddress> envelope) {
    final DnsResponse res = envelope.content();
    if (res.count(DnsSection.QUESTION) != 1) {
        logger.warn("Received a DNS response with invalid number of questions: {}", envelope);
        return;
    }

    if (!question().equals(res.recordAt(DnsSection.QUESTION))) {
        logger.warn("Received a mismatching DNS response: {}", envelope);
        return;
    }

    setSuccess(envelope);
}
 
Example #15
Source File: TcpClientSession.java    From PacketLib with MIT License 4 votes vote down vote up
private void resolveAddress() {
    boolean debug = getFlag(BuiltinFlags.PRINT_DEBUG, false);

    String name = this.getPacketProtocol().getSRVRecordPrefix() + "._tcp." + this.getHost();
    if(debug) {
        System.out.println("[PacketLib] Attempting SRV lookup for \"" + name + "\".");
    }

    AddressedEnvelope<DnsResponse, InetSocketAddress> envelope = null;
    try(DnsNameResolver resolver = new DnsNameResolverBuilder(this.group.next())
            .channelType(NioDatagramChannel.class)
            .build()) {
        envelope = resolver.query(new DefaultDnsQuestion(name, DnsRecordType.SRV)).get();
        DnsResponse response = envelope.content();
        if(response.count(DnsSection.ANSWER) > 0) {
            DefaultDnsRawRecord record = response.recordAt(DnsSection.ANSWER, 0);
            if(record.type() == DnsRecordType.SRV) {
                ByteBuf buf = record.content();
                buf.skipBytes(4); // Skip priority and weight.

                int port = buf.readUnsignedShort();
                String host = DefaultDnsRecordDecoder.decodeName(buf);
                if(host.endsWith(".")) {
                    host = host.substring(0, host.length() - 1);
                }

                if(debug) {
                    System.out.println("[PacketLib] Found SRV record containing \"" + host + ":" + port + "\".");
                }

                this.host = host;
                this.port = port;
            } else if(debug) {
                System.out.println("[PacketLib] Received non-SRV record in response.");
            }
        } else if(debug) {
            System.out.println("[PacketLib] No SRV record found.");
        }
    } catch(Exception e) {
        if(debug) {
            System.out.println("[PacketLib] Failed to resolve SRV record.");
            e.printStackTrace();
        }
    } finally {
        if(envelope != null) {
            envelope.release();
        }
    }
}
 
Example #16
Source File: TestDnsServer.java    From armeria with Apache License 2.0 4 votes vote down vote up
public TestDnsServer(Map<DnsQuestion, DnsResponse> responses) {
    this(responses, null);
}
 
Example #17
Source File: DnsNameResolverTest.java    From netty-4.1.22 with Apache License 2.0 4 votes vote down vote up
private static void queryMx(
        DnsNameResolver resolver,
        Map<String, Future<AddressedEnvelope<DnsResponse, InetSocketAddress>>> futures,
        String hostname) throws Exception {
    futures.put(hostname, resolver.query(new DefaultDnsQuestion(hostname, DnsRecordType.MX)));
}
 
Example #18
Source File: DnsNameResolver.java    From netty-4.1.22 with Apache License 2.0 4 votes vote down vote up
@SuppressWarnings("unchecked")
private static Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> cast(Promise<?> promise) {
    return (Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>>) promise;
}
 
Example #19
Source File: TestDnsServer.java    From armeria with Apache License 2.0 4 votes vote down vote up
public void setResponses(Map<DnsQuestion, DnsResponse> responses) {
    this.responses.values().forEach(DnsResponse::release);
    this.responses = ImmutableMap.copyOf(responses);
}
 
Example #20
Source File: DnsNameResolver.java    From netty-4.1.22 with Apache License 2.0 4 votes vote down vote up
final Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query0(
        InetSocketAddress nameServerAddr, DnsQuestion question,
        DnsRecord[] additionals,
        Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {
    return query0(nameServerAddr, question, additionals, ch.newPromise(), promise);
}
 
Example #21
Source File: DnsNameResolver.java    From netty-4.1.22 with Apache License 2.0 4 votes vote down vote up
/**
 * Sends a DNS query with the specified question.
 */
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
        DnsQuestion question, Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {
    return query(nextNameServerAddress(), question, Collections.<DnsRecord>emptyList(), promise);
}
 
Example #22
Source File: DnsNameResolver.java    From netty-4.1.22 with Apache License 2.0 4 votes vote down vote up
/**
 * Sends a DNS query with the specified question with additional records.
 */
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
        DnsQuestion question, Iterable<DnsRecord> additionals) {
    return query(nextNameServerAddress(), question, additionals);
}
 
Example #23
Source File: DnsNameResolver.java    From netty-4.1.22 with Apache License 2.0 4 votes vote down vote up
/**
 * Sends a DNS query with the specified question.
 */
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(DnsQuestion question) {
    return query(nextNameServerAddress(), question);
}
 
Example #24
Source File: DnsNameResolverContext.java    From netty-4.1.22 with Apache License 2.0 4 votes vote down vote up
private void onResponseCNAME(DnsQuestion question, AddressedEnvelope<DnsResponse, InetSocketAddress> envelope,
                             final DnsQueryLifecycleObserver queryLifecycleObserver,
                             Promise<T> promise) {
    onResponseCNAME(question, envelope, buildAliasMap(envelope.content()), queryLifecycleObserver, promise);
}
 
Example #25
Source File: DnsNameResolverContext.java    From netty-4.1.22 with Apache License 2.0 4 votes vote down vote up
/**
 * Handles a redirect answer if needed and returns {@code true} if a redirect query has been made.
 */
private boolean handleRedirect(
        DnsQuestion question, AddressedEnvelope<DnsResponse, InetSocketAddress> envelope,
        final DnsQueryLifecycleObserver queryLifecycleObserver, 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()) {
                query(parent.uncachedRedirectDnsServerStream(nameServers), 0, question,
                      queryLifecycleObserver.queryRedirected(unmodifiableList(nameServers)), promise, null);
                return true;
            }
        }
    }
    return false;
}
 
Example #26
Source File: DnsNameResolverContext.java    From netty-4.1.22 with Apache License 2.0 4 votes vote down vote up
private void query(final DnsServerAddressStream nameServerAddrStream,
                   final int nameServerAddrStreamIndex,
                   final DnsQuestion question,
                   final DnsQueryLifecycleObserver queryLifecycleObserver,
                   final Promise<T> promise,
                   final Throwable cause) {
    if (nameServerAddrStreamIndex >= nameServerAddrStream.size() || allowedQueries == 0 || promise.isCancelled()) {
        tryToFinishResolve(nameServerAddrStream, nameServerAddrStreamIndex, question, queryLifecycleObserver,
                           promise, cause);
        return;
    }

    --allowedQueries;
    final InetSocketAddress nameServerAddr = nameServerAddrStream.next();
    final ChannelPromise writePromise = parent.ch.newPromise();
    final Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> f = parent.query0(
            nameServerAddr, question, additionals, writePromise,
            parent.ch.eventLoop().<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>>newPromise());
    queriesInProgress.add(f);

    queryLifecycleObserver.queryWritten(nameServerAddr, writePromise);

    f.addListener(new FutureListener<AddressedEnvelope<DnsResponse, InetSocketAddress>>() {
        @Override
        public void operationComplete(Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> future) {
            queriesInProgress.remove(future);

            if (promise.isDone() || future.isCancelled()) {
                queryLifecycleObserver.queryCancelled(allowedQueries);

                // Check if we need to release the envelope itself. If the query was cancelled the getNow() will
                // return null as well as the Future will be failed with a CancellationException.
                AddressedEnvelope<DnsResponse, InetSocketAddress> result = future.getNow();
                if (result != null) {
                    result.release();
                }
                return;
            }

            final Throwable queryCause = future.cause();
            try {
                if (queryCause == null) {
                    onResponse(nameServerAddrStream, nameServerAddrStreamIndex, question, future.getNow(),
                               queryLifecycleObserver, promise);
                } else {
                    // Server did not respond or I/O error occurred; try again.
                    queryLifecycleObserver.queryFailed(queryCause);
                    query(nameServerAddrStream, nameServerAddrStreamIndex + 1, question, promise, queryCause);
                }
            } finally {
                tryToFinishResolve(nameServerAddrStream, nameServerAddrStreamIndex, question,
                                   // queryLifecycleObserver has already been terminated at this point so we must
                                   // not allow it to be terminated again by tryToFinishResolve.
                                   NoopDnsQueryLifecycleObserver.INSTANCE,
                                   promise, queryCause);
            }
        }
    });
}
 
Example #27
Source File: DnsNameResolverContext.java    From netty-4.1.22 with Apache License 2.0 4 votes vote down vote up
@Override
public void operationComplete(Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> future) {
    if (future.isSuccess()) {
        future.getNow().release();
    }
}