Example usage for io.netty.handler.codec.dns DnsRecord type

List of usage examples for io.netty.handler.codec.dns DnsRecord type

Introduction

In this page you can find the example usage for io.netty.handler.codec.dns DnsRecord type.

Prototype

DnsRecordType type();

Source Link

Document

Returns the type of this resource record.

Usage

From source file:com.linecorp.armeria.client.endpoint.dns.DnsAddressEndpointGroup.java

License:Apache License

@Override
ImmutableSortedSet<Endpoint> onDnsRecords(List<DnsRecord> records, int ttl) throws Exception {
    final ImmutableSortedSet.Builder<Endpoint> builder = ImmutableSortedSet.naturalOrder();
    final boolean hasLoopbackARecords = records.stream().filter(r -> r instanceof DnsRawRecord)
            .map(DnsRawRecord.class::cast).anyMatch(
                    r -> r.type() == DnsRecordType.A && r.content().getByte(r.content().readerIndex()) == 127);

    for (DnsRecord r : records) {
        if (!(r instanceof DnsRawRecord)) {
            continue;
        }/*from  w w w . ja  va 2 s .  com*/

        final DnsRecordType type = r.type();
        final ByteBuf content = ((ByteBufHolder) r).content();
        final int contentLen = content.readableBytes();

        // Skip invalid records.
        if (type == DnsRecordType.A) {
            if (contentLen != 4) {
                warnInvalidRecord(DnsRecordType.A, content);
                continue;
            }
        } else if (type == DnsRecordType.AAAA) {
            if (contentLen != 16) {
                warnInvalidRecord(DnsRecordType.AAAA, content);
                continue;
            }
        } else {
            continue;
        }

        // Convert the content into an IP address and then into an endpoint.
        final String ipAddr;
        final byte[] addrBytes = new byte[contentLen];
        content.getBytes(content.readerIndex(), addrBytes);

        if (contentLen == 16) {
            // Convert some IPv6 addresses into IPv4 addresses to remove duplicate endpoints.
            if (addrBytes[0] == 0x00 && addrBytes[1] == 0x00 && addrBytes[2] == 0x00 && addrBytes[3] == 0x00
                    && addrBytes[4] == 0x00 && addrBytes[5] == 0x00 && addrBytes[6] == 0x00
                    && addrBytes[7] == 0x00 && addrBytes[8] == 0x00 && addrBytes[9] == 0x00) {

                if (addrBytes[10] == 0x00 && addrBytes[11] == 0x00) {
                    if (addrBytes[12] == 0x00 && addrBytes[13] == 0x00 && addrBytes[14] == 0x00
                            && addrBytes[15] == 0x01) {
                        // Loopback address (::1)
                        if (hasLoopbackARecords) {
                            // Contains an IPv4 loopback address already; skip.
                            continue;
                        } else {
                            ipAddr = "::1";
                        }
                    } else {
                        // IPv4-compatible address.
                        ipAddr = NetUtil.bytesToIpAddress(addrBytes, 12, 4);
                    }
                } else if (addrBytes[10] == -1 && addrBytes[11] == -1) {
                    // IPv4-mapped address.
                    ipAddr = NetUtil.bytesToIpAddress(addrBytes, 12, 4);
                } else {
                    ipAddr = NetUtil.bytesToIpAddress(addrBytes);
                }
            } else {
                ipAddr = NetUtil.bytesToIpAddress(addrBytes);
            }
        } else {
            ipAddr = NetUtil.bytesToIpAddress(addrBytes);
        }

        final Endpoint endpoint = port != 0 ? Endpoint.of(hostname, port) : Endpoint.of(hostname);
        builder.add(endpoint.withIpAddr(ipAddr));
    }

    final ImmutableSortedSet<Endpoint> endpoints = builder.build();
    if (logger().isDebugEnabled()) {
        logger().debug("{} Resolved: {} (TTL: {})", logPrefix(),
                endpoints.stream().map(Endpoint::ipAddr).collect(Collectors.joining(", ")), ttl);
    }

    return endpoints;
}

From source file:com.linecorp.armeria.client.endpoint.dns.DnsServiceEndpointGroup.java

License:Apache License

@Override
ImmutableSortedSet<Endpoint> onDnsRecords(List<DnsRecord> records, int ttl) throws Exception {
    final ImmutableSortedSet.Builder<Endpoint> builder = ImmutableSortedSet.naturalOrder();
    for (DnsRecord r : records) {
        if (!(r instanceof DnsRawRecord) || r.type() != DnsRecordType.SRV) {
            continue;
        }// w w  w  . jav a 2 s .  c o  m

        final ByteBuf content = ((ByteBufHolder) r).content();
        if (content.readableBytes() <= 6) { // Too few bytes
            warnInvalidRecord(DnsRecordType.SRV, content);
            continue;
        }

        content.markReaderIndex();
        content.skipBytes(2); // priority unused
        final int weight = content.readUnsignedShort();
        final int port = content.readUnsignedShort();

        final Endpoint endpoint;
        try {
            final String target = stripTrailingDot(DefaultDnsRecordDecoder.decodeName(content));
            endpoint = port > 0 ? Endpoint.of(target, port) : Endpoint.of(target);
        } catch (Exception e) {
            content.resetReaderIndex();
            warnInvalidRecord(DnsRecordType.SRV, content);
            continue;
        }

        builder.add(endpoint.withWeight(weight));
    }

    final ImmutableSortedSet<Endpoint> endpoints = builder.build();
    if (logger().isDebugEnabled()) {
        logger().debug("{} Resolved: {} (TTL: {})", logPrefix(),
                endpoints.stream().map(e -> e.authority() + '/' + e.weight()).collect(Collectors.joining(", ")),
                ttl);
    }

    return endpoints;
}

From source file:com.linecorp.armeria.client.endpoint.dns.DnsTextEndpointGroup.java

License:Apache License

@Override
ImmutableSortedSet<Endpoint> onDnsRecords(List<DnsRecord> records, int ttl) throws Exception {
    final ImmutableSortedSet.Builder<Endpoint> builder = ImmutableSortedSet.naturalOrder();
    for (DnsRecord r : records) {
        if (!(r instanceof DnsRawRecord) || r.type() != DnsRecordType.TXT) {
            continue;
        }/*from w  w  w  . j av  a  2 s . c o m*/

        final ByteBuf content = ((ByteBufHolder) r).content();
        if (!content.isReadable()) { // Missing length octet
            warnInvalidRecord(DnsRecordType.TXT, content);
            continue;
        }

        content.markReaderIndex();
        final int txtLen = content.readUnsignedByte();
        if (txtLen == 0) { // Empty content
            continue;
        }

        if (content.readableBytes() != txtLen) { // Mismatching number of octets
            content.resetReaderIndex();
            warnInvalidRecord(DnsRecordType.TXT, content);
            continue;
        }

        final byte[] txt = new byte[txtLen];
        content.readBytes(txt);

        final Endpoint endpoint;
        try {
            endpoint = mapping.apply(txt);
        } catch (Exception e) {
            content.resetReaderIndex();
            warnInvalidRecord(DnsRecordType.TXT, content);
            continue;
        }

        if (endpoint != null) {
            if (endpoint.isGroup()) {
                logger().warn("{} Ignoring group endpoint: {}", logPrefix(), endpoint);
            } else {
                builder.add(endpoint);
            }
        }
    }

    final ImmutableSortedSet<Endpoint> endpoints = builder.build();
    if (logger().isDebugEnabled()) {
        logger().debug("{} Resolved: {} (TTL: {})", logPrefix(),
                endpoints.stream().map(Object::toString).collect(Collectors.joining(", ")), ttl);
    }

    return endpoints;
}

From source file:io.vertx.core.dns.impl.decoder.RecordDecoder.java

License:Open Source License

/**
 * Decodes a resource record and returns the result.
 *
 * @param record/*from  w ww.ja  va 2 s .  c om*/
 * @return the decoded resource record
 */
@SuppressWarnings("unchecked")
public static <T> T decode(DnsRecord record) {
    DnsRecordType type = record.type();
    Function<DnsRecord, ?> decoder = decoders.get(type);
    if (decoder == null) {
        throw new IllegalStateException("Unsupported resource record type [id: " + type + "].");
    }
    T result = null;
    try {
        result = (T) decoder.apply(record);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;
}

From source file:io.vertx.core.dns.impl.DnsClientImpl.java

License:Open Source License

@SuppressWarnings("unchecked")
private <T> void lookup(String name, Future<List<T>> result, DnsRecordType... types) {
    Objects.requireNonNull(name, "no null name accepted");
    bootstrap.connect(dnsServer).addListener(new RetryChannelFutureListener(result) {
        @Override/*  ww  w  .ja va 2  s  . c om*/
        public void onSuccess(ChannelFuture future) throws Exception {
            DatagramDnsQuery query = new DatagramDnsQuery(null, dnsServer,
                    ThreadLocalRandom.current().nextInt());
            for (DnsRecordType type : types) {
                query.addRecord(DnsSection.QUESTION, new DefaultDnsQuestion(name, type, DnsRecord.CLASS_IN));
            }
            future.channel().writeAndFlush(query).addListener(new RetryChannelFutureListener(result) {
                @Override
                public void onSuccess(ChannelFuture future) throws Exception {
                    future.channel().pipeline().addLast(new SimpleChannelInboundHandler<DnsResponse>() {
                        @Override
                        protected void channelRead0(ChannelHandlerContext ctx, DnsResponse msg)
                                throws Exception {
                            DnsResponseCode code = DnsResponseCode.valueOf(msg.code().intValue());

                            if (code == DnsResponseCode.NOERROR) {

                                int count = msg.count(DnsSection.ANSWER);

                                List<T> records = new ArrayList<>(count);
                                for (int idx = 0; idx < count; idx++) {
                                    DnsRecord a = msg.recordAt(DnsSection.ANSWER, idx);
                                    T record = RecordDecoder.decode(a);
                                    if (isRequestedType(a.type(), types)) {
                                        records.add(record);
                                    }
                                }

                                if (records.size() > 0 && (records.get(0) instanceof MxRecordImpl
                                        || records.get(0) instanceof SrvRecordImpl)) {
                                    Collections.sort((List) records);
                                }

                                setResult(result, records);
                            } else {
                                setFailure(result, new DnsException(code));
                            }
                            ctx.close();
                        }

                        private boolean isRequestedType(DnsRecordType dnsRecordType, DnsRecordType[] types) {
                            for (DnsRecordType t : types) {
                                if (t.equals(dnsRecordType)) {
                                    return true;
                                }
                            }
                            return false;
                        }

                        @Override
                        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
                                throws Exception {
                            setFailure(result, cause);
                            ctx.close();
                        }
                    });
                }
            });
        }
    });
}

From source file:io.vertx.core.dns.impl.fix.DnsNameResolverContext.java

License:Apache License

private void onResponseAorAAAA(DnsRecordType qType, DnsQuestion question,
        AddressedEnvelope<DnsResponse, InetSocketAddress> envelope) {

    // 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;
        }//from   w w  w. ja v a 2  s . co m

        final String qName = question.name().toLowerCase(Locale.US);
        final String rName = r.name().toLowerCase(Locale.US);

        // Make sure the record is for the questioned domain.
        if (!rName.equals(qName)) {
            // Even if the record's name is not exactly same, it might be an alias defined in the CNAME records.
            String resolved = qName;
            do {
                resolved = cnames.get(resolved);
                if (rName.equals(resolved)) {
                    break;
                }
            } while (resolved != null);

            if (resolved == null) {
                continue;
            }
        }

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

        final ByteBuf content = ((ByteBufHolder) r).content();
        final int contentLen = content.readableBytes();
        if (contentLen != INADDRSZ4 && contentLen != INADDRSZ6) {
            continue;
        }

        final byte[] addrBytes = new byte[contentLen];
        content.getBytes(content.readerIndex(), addrBytes);

        final InetAddress resolved;
        try {
            resolved = InetAddress.getByAddress(hostname, addrBytes);
        } catch (UnknownHostException e) {
            // Should never reach here.
            throw new Error(e);
        }

        if (resolvedEntries == null) {
            resolvedEntries = new ArrayList<DnsCacheEntry>(8);
        }

        final DnsCacheEntry e = new DnsCacheEntry(hostname, resolved);
        resolveCache.cache(hostname, 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);
    }
}

From source file:io.vertx.core.dns.impl.fix.DnsNameResolverContext.java

License:Apache License

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;
        }/*from w  w  w  .  j a v  a  2 s .  com*/

        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>();
        }

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

    return cnames != null ? cnames : Collections.<String, String>emptyMap();
}