summaryrefslogtreecommitdiff
path: root/src/javax/jmdns/impl/DNSQuestion.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/javax/jmdns/impl/DNSQuestion.java')
-rw-r--r--src/javax/jmdns/impl/DNSQuestion.java328
1 files changed, 328 insertions, 0 deletions
diff --git a/src/javax/jmdns/impl/DNSQuestion.java b/src/javax/jmdns/impl/DNSQuestion.java
new file mode 100644
index 0000000..2125bc8
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSQuestion.java
@@ -0,0 +1,328 @@
+// Copyright 2003-2005 Arthur van Hoff, Rick Blair
+// Licensed under Apache License version 2.0
+// Original license LGPL
+
+package javax.jmdns.impl;
+
+import java.net.InetAddress;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.ServiceInfo.Fields;
+import javax.jmdns.impl.JmDNSImpl.ServiceTypeEntry;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSRecordClass;
+import javax.jmdns.impl.constants.DNSRecordType;
+
+/**
+ * A DNS question.
+ *
+ * @author Arthur van Hoff, Pierre Frisch
+ */
+public class DNSQuestion extends DNSEntry {
+ private static Logger logger = Logger.getLogger(DNSQuestion.class.getName());
+
+ /**
+ * Address question.
+ */
+ private static class DNS4Address extends DNSQuestion {
+ DNS4Address(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ super(name, type, recordClass, unique);
+ }
+
+ @Override
+ public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+ DNSRecord answer = jmDNSImpl.getLocalHost().getDNSAddressRecord(this.getRecordType(), DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL);
+ if (answer != null) {
+ answers.add(answer);
+ }
+ }
+
+ @Override
+ public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+ String name = this.getName().toLowerCase();
+ return jmDNSImpl.getLocalHost().getName().equals(name) || jmDNSImpl.getServices().keySet().contains(name);
+ }
+
+ }
+
+ /**
+ * Address question.
+ */
+ private static class DNS6Address extends DNSQuestion {
+ DNS6Address(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ super(name, type, recordClass, unique);
+ }
+
+ @Override
+ public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+ DNSRecord answer = jmDNSImpl.getLocalHost().getDNSAddressRecord(this.getRecordType(), DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL);
+ if (answer != null) {
+ answers.add(answer);
+ }
+ }
+
+ @Override
+ public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+ String name = this.getName().toLowerCase();
+ return jmDNSImpl.getLocalHost().getName().equals(name) || jmDNSImpl.getServices().keySet().contains(name);
+ }
+
+ }
+
+ /**
+ * Host Information question.
+ */
+ private static class HostInformation extends DNSQuestion {
+ HostInformation(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ super(name, type, recordClass, unique);
+ }
+ }
+
+ /**
+ * Pointer question.
+ */
+ private static class Pointer extends DNSQuestion {
+ Pointer(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ super(name, type, recordClass, unique);
+ }
+
+ @Override
+ public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+ // find matching services
+ for (ServiceInfo serviceInfo : jmDNSImpl.getServices().values()) {
+ this.addAnswersForServiceInfo(jmDNSImpl, answers, (ServiceInfoImpl) serviceInfo);
+ }
+ if (this.isServicesDiscoveryMetaQuery()) {
+ for (String serviceType : jmDNSImpl.getServiceTypes().keySet()) {
+ ServiceTypeEntry typeEntry = jmDNSImpl.getServiceTypes().get(serviceType);
+ answers.add(new DNSRecord.Pointer("_services._dns-sd._udp.local.", DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE, DNSConstants.DNS_TTL, typeEntry.getType()));
+ }
+ } else if (this.isReverseLookup()) {
+ String ipValue = this.getQualifiedNameMap().get(Fields.Instance);
+ if ((ipValue != null) && (ipValue.length() > 0)) {
+ InetAddress address = jmDNSImpl.getLocalHost().getInetAddress();
+ String hostIPAddress = (address != null ? address.getHostAddress() : "");
+ if (ipValue.equalsIgnoreCase(hostIPAddress)) {
+ if (this.isV4ReverseLookup()) {
+ answers.add(jmDNSImpl.getLocalHost().getDNSReverseAddressRecord(DNSRecordType.TYPE_A, DNSRecordClass.NOT_UNIQUE, DNSConstants.DNS_TTL));
+ }
+ if (this.isV6ReverseLookup()) {
+ answers.add(jmDNSImpl.getLocalHost().getDNSReverseAddressRecord(DNSRecordType.TYPE_AAAA, DNSRecordClass.NOT_UNIQUE, DNSConstants.DNS_TTL));
+ }
+ }
+ }
+ } else if (this.isDomainDiscoveryQuery()) {
+ // FIXME [PJYF Nov 16 2010] We do not currently support domain discovery
+ }
+ }
+
+ }
+
+ /**
+ * Service question.
+ */
+ private static class Service extends DNSQuestion {
+ Service(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ super(name, type, recordClass, unique);
+ }
+
+ @Override
+ public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+ String loname = this.getName().toLowerCase();
+ if (jmDNSImpl.getLocalHost().getName().equalsIgnoreCase(loname)) {
+ // type = DNSConstants.TYPE_A;
+ answers.addAll(jmDNSImpl.getLocalHost().answers(this.isUnique(), DNSConstants.DNS_TTL));
+ return;
+ }
+ // Service type request
+ if (jmDNSImpl.getServiceTypes().containsKey(loname)) {
+ DNSQuestion question = new Pointer(this.getName(), DNSRecordType.TYPE_PTR, this.getRecordClass(), this.isUnique());
+ question.addAnswers(jmDNSImpl, answers);
+ return;
+ }
+
+ this.addAnswersForServiceInfo(jmDNSImpl, answers, (ServiceInfoImpl) jmDNSImpl.getServices().get(loname));
+ }
+
+ @Override
+ public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+ String name = this.getName().toLowerCase();
+ return jmDNSImpl.getLocalHost().getName().equals(name) || jmDNSImpl.getServices().keySet().contains(name);
+ }
+
+ }
+
+ /**
+ * Text question.
+ */
+ private static class Text extends DNSQuestion {
+ Text(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ super(name, type, recordClass, unique);
+ }
+
+ @Override
+ public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+ this.addAnswersForServiceInfo(jmDNSImpl, answers, (ServiceInfoImpl) jmDNSImpl.getServices().get(this.getName().toLowerCase()));
+ }
+
+ @Override
+ public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+ String name = this.getName().toLowerCase();
+ return jmDNSImpl.getLocalHost().getName().equals(name) || jmDNSImpl.getServices().keySet().contains(name);
+ }
+
+ }
+
+ /**
+ * AllRecords question.
+ */
+ private static class AllRecords extends DNSQuestion {
+ AllRecords(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ super(name, type, recordClass, unique);
+ }
+
+ @Override
+ public boolean isSameType(DNSEntry entry) {
+ // We match all non null entry
+ return (entry != null);
+ }
+
+ @Override
+ public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+ String loname = this.getName().toLowerCase();
+ if (jmDNSImpl.getLocalHost().getName().equalsIgnoreCase(loname)) {
+ // type = DNSConstants.TYPE_A;
+ answers.addAll(jmDNSImpl.getLocalHost().answers(this.isUnique(), DNSConstants.DNS_TTL));
+ return;
+ }
+ // Service type request
+ if (jmDNSImpl.getServiceTypes().containsKey(loname)) {
+ DNSQuestion question = new Pointer(this.getName(), DNSRecordType.TYPE_PTR, this.getRecordClass(), this.isUnique());
+ question.addAnswers(jmDNSImpl, answers);
+ return;
+ }
+
+ this.addAnswersForServiceInfo(jmDNSImpl, answers, (ServiceInfoImpl) jmDNSImpl.getServices().get(loname));
+ }
+
+ @Override
+ public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+ String name = this.getName().toLowerCase();
+ return jmDNSImpl.getLocalHost().getName().equals(name) || jmDNSImpl.getServices().keySet().contains(name);
+ }
+
+ }
+
+ DNSQuestion(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ super(name, type, recordClass, unique);
+ }
+
+ /**
+ * Create a question.
+ *
+ * @param name
+ * DNS name to be resolved
+ * @param type
+ * Record type to resolve
+ * @param recordClass
+ * Record class to resolve
+ * @param unique
+ * Request unicast response (Currently not supported in this implementation)
+ * @return new question
+ */
+ public static DNSQuestion newQuestion(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) {
+ switch (type) {
+ case TYPE_A:
+ return new DNS4Address(name, type, recordClass, unique);
+ case TYPE_A6:
+ return new DNS6Address(name, type, recordClass, unique);
+ case TYPE_AAAA:
+ return new DNS6Address(name, type, recordClass, unique);
+ case TYPE_ANY:
+ return new AllRecords(name, type, recordClass, unique);
+ case TYPE_HINFO:
+ return new HostInformation(name, type, recordClass, unique);
+ case TYPE_PTR:
+ return new Pointer(name, type, recordClass, unique);
+ case TYPE_SRV:
+ return new Service(name, type, recordClass, unique);
+ case TYPE_TXT:
+ return new Text(name, type, recordClass, unique);
+ default:
+ return new DNSQuestion(name, type, recordClass, unique);
+ }
+ }
+
+ /**
+ * Check if this question is answered by a given DNS record.
+ */
+ boolean answeredBy(DNSEntry rec) {
+ return this.isSameRecordClass(rec) && this.isSameType(rec) && this.getName().equals(rec.getName());
+ }
+
+ /**
+ * Adds answers to the list for our question.
+ *
+ * @param jmDNSImpl
+ * DNS holding the records
+ * @param answers
+ * List of previous answer to append.
+ */
+ public void addAnswers(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers) {
+ // By default we do nothing
+ }
+
+ protected void addAnswersForServiceInfo(JmDNSImpl jmDNSImpl, Set<DNSRecord> answers, ServiceInfoImpl info) {
+ if ((info != null) && info.isAnnounced()) {
+ if (this.getName().equalsIgnoreCase(info.getQualifiedName()) || this.getName().equalsIgnoreCase(info.getType())) {
+ answers.addAll(jmDNSImpl.getLocalHost().answers(DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL));
+ answers.addAll(info.answers(DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL, jmDNSImpl.getLocalHost()));
+ }
+ if (logger.isLoggable(Level.FINER)) {
+ logger.finer(jmDNSImpl.getName() + " DNSQuestion(" + this.getName() + ").addAnswersForServiceInfo(): info: " + info + "\n" + answers);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.jmdns.impl.DNSEntry#isStale(long)
+ */
+ @Override
+ public boolean isStale(long now) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.jmdns.impl.DNSEntry#isExpired(long)
+ */
+ @Override
+ public boolean isExpired(long now) {
+ return false;
+ }
+
+ /**
+ * Checks if we are the only to be able to answer that question.
+ *
+ * @param jmDNSImpl
+ * DNS holding the records
+ * @return <code>true</code> if we are the only one with the answer to the question, <code>false</code> otherwise.
+ */
+ public boolean iAmTheOnlyOne(JmDNSImpl jmDNSImpl) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.jmdns.impl.DNSEntry#toString(java.lang.StringBuilder)
+ */
+ @Override
+ public void toString(StringBuilder aLog) {
+ // do nothing
+ }
+
+} \ No newline at end of file