
org.minidns.hla.SrvResolverResult Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of minidns-hla Show documentation
Show all versions of minidns-hla Show documentation
A DNS library for Java and Android systems
The newest version!
/*
* Copyright 2015-2024 the original author or authors
*
* This software is licensed under the Apache License, Version 2.0,
* the GNU Lesser General Public License version 2 or later ("LGPL")
* and the WTFPL.
* You may choose either license to govern your use of this software only
* upon the condition that you accept all of the terms of either
* the Apache License 2.0, the LGPL 2.1+ or the WTFPL.
*/
package org.minidns.hla;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Set;
import org.minidns.AbstractDnsClient.IpVersionSetting;
import org.minidns.MiniDnsException.NullResultException;
import org.minidns.dnsname.DnsName;
import org.minidns.hla.srv.SrvServiceProto;
import org.minidns.record.A;
import org.minidns.record.AAAA;
import org.minidns.record.InternetAddressRR;
import org.minidns.record.SRV;
import org.minidns.util.SrvUtil;
public class SrvResolverResult extends ResolverResult {
private final ResolverApi resolver;
private final IpVersionSetting ipVersion;
private final SrvServiceProto srvServiceProto;
private List sortedSrvResolvedAddresses;
SrvResolverResult(ResolverResult srvResult, SrvServiceProto srvServiceProto, ResolverApi resolver) throws NullResultException {
super(srvResult.question, srvResult.result, srvResult.unverifiedReasons);
this.resolver = resolver;
this.ipVersion = resolver.getClient().getPreferedIpVersion();
this.srvServiceProto = srvServiceProto;
}
/**
* Get a list ordered by priority and weight of the resolved SRV records. This method will throw if there was an
* error response or if subsequent {@link A} or {@link AAAA} resource record lookups fail. It will return
* {@code null} in case the service is decidedly not available at this domain.
*
* @return a list ordered by priority and weight of the related SRV records.
* @throws IOException in case an I/O error occurs.
*/
public List getSortedSrvResolvedAddresses() throws IOException {
if (sortedSrvResolvedAddresses != null) {
return sortedSrvResolvedAddresses;
}
throwIseIfErrorResponse();
if (isServiceDecidedlyNotAvailableAtThisDomain()) {
return null;
}
List srvRecords = SrvUtil.sortSrvRecords(getAnswers());
List res = new ArrayList<>(srvRecords.size());
for (SRV srvRecord : srvRecords) {
ResolverResult aRecordsResult = null;
ResolverResult aaaaRecordsResult = null;
Set aRecords = Collections.emptySet();
if (ipVersion.v4) {
aRecordsResult = resolver.resolve(srvRecord.target, A.class);
if (aRecordsResult.wasSuccessful() && !aRecordsResult.hasUnverifiedReasons()) {
aRecords = aRecordsResult.getAnswers();
}
}
Set aaaaRecords = Collections.emptySet();
if (ipVersion.v6) {
aaaaRecordsResult = resolver.resolve(srvRecord.target, AAAA.class);
if (aaaaRecordsResult.wasSuccessful() && !aaaaRecordsResult.hasUnverifiedReasons()) {
aaaaRecords = aaaaRecordsResult.getAnswers();
}
}
if (aRecords.isEmpty() && aaaaRecords.isEmpty()) {
// TODO Possibly check for (C|D)NAME usage and throw a meaningful exception that it is not allowed for
// the target of an SRV to be an alias as per RFC 2782.
/*
ResolverResult cnameRecordResult = resolve(srvRecord.name, CNAME.class);
if (cnameRecordResult.wasSuccessful()) {
}
*/
continue;
}
List> srvAddresses = new ArrayList<>(aRecords.size() + aaaaRecords.size());
switch (ipVersion) {
case v4only:
srvAddresses.addAll(aRecords);
break;
case v6only:
srvAddresses.addAll(aaaaRecords);
break;
case v4v6:
srvAddresses.addAll(aRecords);
srvAddresses.addAll(aaaaRecords);
break;
case v6v4:
srvAddresses.addAll(aaaaRecords);
srvAddresses.addAll(aRecords);
break;
}
ResolvedSrvRecord resolvedSrvAddresses = new ResolvedSrvRecord(question.name, srvServiceProto, srvRecord, srvAddresses,
aRecordsResult, aaaaRecordsResult);
res.add(resolvedSrvAddresses);
}
sortedSrvResolvedAddresses = res;
return res;
}
public boolean isServiceDecidedlyNotAvailableAtThisDomain() {
Set answers = getAnswers();
if (answers.size() != 1) {
return false;
}
SRV singleAnswer = answers.iterator().next();
return !singleAnswer.isServiceAvailable();
}
public static final class ResolvedSrvRecord {
public final DnsName name;
public final SrvServiceProto srvServiceProto;
public final SRV srv;
public final List> addresses;
public final ResolverResult aRecordsResult;
public final ResolverResult aaaaRecordsResult;
/**
* The port announced by the SRV RR. This is simply a shortcut for srv.port
.
*/
public final int port;
private ResolvedSrvRecord(DnsName name, SrvServiceProto srvServiceProto, SRV srv,
List> addresses, ResolverResult aRecordsResult,
ResolverResult aaaaRecordsResult) {
this.name = name;
this.srvServiceProto = srvServiceProto;
this.srv = srv;
this.addresses = Collections.unmodifiableList(addresses);
this.port = srv.port;
this.aRecordsResult = aRecordsResult;
this.aaaaRecordsResult = aaaaRecordsResult;
}
}
/**
* Convenience method to sort multiple resolved SRV RRs. This is for example required by XEP-0368, where
* {@link org.minidns.hla.srv.SrvService#xmpp_client} and {@link org.minidns.hla.srv.SrvService#xmpps_client} may be
* sorted together.
*
* @param resolvedSrvRecordCollections a collection of resolved SRV records.
* @return a list ordered by priority and weight of the related SRV records.
*/
@SafeVarargs
public static List sortMultiple(Collection... resolvedSrvRecordCollections) {
int srvRecordsCount = 0;
for (Collection resolvedSrvRecords : resolvedSrvRecordCollections) {
if (resolvedSrvRecords == null) {
continue;
}
srvRecordsCount += resolvedSrvRecords.size();
}
List srvToSort = new ArrayList<>(srvRecordsCount);
IdentityHashMap identityMap = new IdentityHashMap<>(srvRecordsCount);
for (Collection resolvedSrvRecords : resolvedSrvRecordCollections) {
if (resolvedSrvRecords == null) {
continue;
}
for (ResolvedSrvRecord resolvedSrvRecord : resolvedSrvRecords) {
srvToSort.add(resolvedSrvRecord.srv);
identityMap.put(resolvedSrvRecord.srv, resolvedSrvRecord);
}
}
List sortedSrvs = SrvUtil.sortSrvRecords(srvToSort);
assert sortedSrvs.size() == srvRecordsCount;
List res = new ArrayList<>(srvRecordsCount);
for (SRV sortedSrv : sortedSrvs) {
ResolvedSrvRecord resolvedSrvRecord = identityMap.get(sortedSrv);
res.add(resolvedSrvRecord);
}
return res;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy