/** * * Copyright 2013-2017 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.smack.util.dns; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; import java.util.List; import java.util.logging.Logger; import org.jivesoftware.smack.ConnectionConfiguration.DnssecMode; /** * Implementations of this interface define a class that is capable of resolving DNS addresses. * */ public abstract class DNSResolver { protected static final Logger LOGGER = Logger.getLogger(DNSResolver.class.getName()); private final boolean supportsDnssec; protected DNSResolver(boolean supportsDnssec) { this.supportsDnssec = supportsDnssec; } /** * Gets a list of service records for the specified service. * @param name The symbolic name of the service. * @return The list of SRV records mapped to the service name. */ public final List lookupSRVRecords(String name, List failedAddresses, DnssecMode dnssecMode) { checkIfDnssecRequestedAndSupported(dnssecMode); return lookupSRVRecords0(name, failedAddresses, dnssecMode); } protected abstract List lookupSRVRecords0(String name, List failedAddresses, DnssecMode dnssecMode); public final HostAddress lookupHostAddress(String name, int port, List failedAddresses, DnssecMode dnssecMode) { checkIfDnssecRequestedAndSupported(dnssecMode); List inetAddresses = lookupHostAddress0(name, failedAddresses, dnssecMode); if (inetAddresses == null || inetAddresses.isEmpty()) { return null; } return new HostAddress(name, port, inetAddresses); } /** * Lookup the IP addresses of a given host name. Returns null if there was an error, in which the error * reason will be added in form of a HostAddress to failedAddresses. Returns a empty list * in case the DNS name exists but has no associated A or AAAA resource records. Otherwise, if the resolution was * successful and there is at least one A or AAAA resource record, then a non-empty list will be returned. *

* Concrete DNS resolver implementations are free to overwrite this, but have to stick to the interface contract. *

* * @param name the DNS name to lookup * @param failedAddresses a list with the failed addresses * @param dnssecMode the selected DNSSEC mode * @return A list, either empty or non-empty, or null */ protected List lookupHostAddress0(String name, List failedAddresses, DnssecMode dnssecMode) { // Default implementation of a DNS name lookup for A/AAAA records. It is assumed that this method does never // support DNSSEC. Subclasses are free to override this method. if (dnssecMode != DnssecMode.disabled) { throw new UnsupportedOperationException("This resolver does not support DNSSEC"); } InetAddress[] inetAddressArray; try { inetAddressArray = InetAddress.getAllByName(name); } catch (UnknownHostException e) { failedAddresses.add(new HostAddress(name, e)); return null; } return Arrays.asList(inetAddressArray); } private final void checkIfDnssecRequestedAndSupported(DnssecMode dnssecMode) { if (dnssecMode != DnssecMode.disabled && !supportsDnssec) { throw new UnsupportedOperationException("This resolver does not support DNSSEC"); } } }