Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'providers/bundles/org.eclipse.ecf.provider.jmdns/jmdns/javax/jmdns/impl/tasks/Responder.java')
-rw-r--r--providers/bundles/org.eclipse.ecf.provider.jmdns/jmdns/javax/jmdns/impl/tasks/Responder.java347
1 files changed, 228 insertions, 119 deletions
diff --git a/providers/bundles/org.eclipse.ecf.provider.jmdns/jmdns/javax/jmdns/impl/tasks/Responder.java b/providers/bundles/org.eclipse.ecf.provider.jmdns/jmdns/javax/jmdns/impl/tasks/Responder.java
index 069a78941..82eef09f9 100644
--- a/providers/bundles/org.eclipse.ecf.provider.jmdns/jmdns/javax/jmdns/impl/tasks/Responder.java
+++ b/providers/bundles/org.eclipse.ecf.provider.jmdns/jmdns/javax/jmdns/impl/tasks/Responder.java
@@ -4,178 +4,287 @@
package javax.jmdns.impl.tasks;
+import java.net.InetAddress;
import java.util.HashSet;
-import java.util.Set;
-import java.util.Timer;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import java.util.Iterator;
+import java.util.TimerTask;
+//import java.util.logging.Level;
+//import java.util.logging.Logger;
+import javax.jmdns.impl.DNSConstants;
+import javax.jmdns.impl.DNSEntry;
import javax.jmdns.impl.DNSIncoming;
import javax.jmdns.impl.DNSOutgoing;
import javax.jmdns.impl.DNSQuestion;
import javax.jmdns.impl.DNSRecord;
+import javax.jmdns.impl.DNSState;
import javax.jmdns.impl.JmDNSImpl;
-import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.ServiceInfoImpl;
/**
- * The Responder sends a single answer for the specified service infos and for the host name.
+ * The Responder sends a single answer for the specified service infos
+ * and for the host name.
*/
-public class Responder extends DNSTask
+public class Responder extends TimerTask
{
- static Logger logger = Logger.getLogger(Responder.class.getName());
+// static Logger logger = Logger.getLogger(Responder.class.getName());
/**
- *
+ *
*/
- private DNSIncoming _in;
+ private final JmDNSImpl jmDNSImpl;
+ private DNSIncoming in;
+ private InetAddress addr;
+ private int port;
- /**
- *
- */
- private boolean _unicast;
-
- public Responder(JmDNSImpl jmDNSImpl, DNSIncoming in, int port)
- {
- super(jmDNSImpl);
- this._in = in;
- this._unicast = (port != DNSConstants.MDNS_PORT);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see javax.jmdns.impl.tasks.DNSTask#getName()
- */
- @Override
- public String getName()
+ public Responder(JmDNSImpl jmDNSImpl, DNSIncoming in, InetAddress addr, int port)
{
- return "Responder(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
+ this.jmDNSImpl = jmDNSImpl;
+ this.in = in;
+ this.addr = addr;
+ this.port = port;
}
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString()
+ public void start()
{
- return super.toString() + " incomming: " + _in;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see javax.jmdns.impl.tasks.DNSTask#start(java.util.Timer)
- */
- @Override
- public void start(Timer timer)
- {
- // According to draft-cheshire-dnsext-multicastdns.txt chapter "7 Responding":
- // We respond immediately if we know for sure, that we are the only one who can respond to the query.
+ // According to draft-cheshire-dnsext-multicastdns.txt
+ // chapter "8 Responding":
+ // We respond immediately if we know for sure, that we are
+ // the only one who can respond to the query.
// In all other cases, we respond within 20-120 ms.
//
- // According to draft-cheshire-dnsext-multicastdns.txt chapter "6.2 Multi-Packet Known Answer Suppression":
+ // According to draft-cheshire-dnsext-multicastdns.txt
+ // chapter "7.2 Multi-Packet Known Answer Suppression":
// We respond after 20-120 ms if the query is truncated.
boolean iAmTheOnlyOne = true;
- for (DNSQuestion question : _in.getQuestions())
+ for (Iterator i = in.getQuestions().iterator(); i.hasNext();)
{
- if (logger.isLoggable(Level.FINEST))
- {
- logger.finest(this.getName() + "start() question=" + question);
- }
- iAmTheOnlyOne = question.iAmTheOnlyOne(this.getDns());
- if (!iAmTheOnlyOne)
+ DNSEntry entry = (DNSEntry) i.next();
+ if (entry instanceof DNSQuestion)
{
- break;
+ DNSQuestion q = (DNSQuestion) entry;
+// logger.finest("start() question=" + q);
+ iAmTheOnlyOne &= (q.getType() == DNSConstants.TYPE_SRV
+ || q.getType() == DNSConstants.TYPE_TXT
+ || q.getType() == DNSConstants.TYPE_A
+ || q.getType() == DNSConstants.TYPE_AAAA
+ || this.jmDNSImpl.getLocalHost().getName().equalsIgnoreCase(q.getName())
+ || this.jmDNSImpl.getServices().containsKey(q.getName().toLowerCase()));
+ if (!iAmTheOnlyOne)
+ {
+ break;
+ }
}
}
- int delay = (iAmTheOnlyOne && !_in.isTruncated()) ? 0 : DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + JmDNSImpl.getRandom().nextInt(DNSConstants.RESPONSE_MAX_WAIT_INTERVAL - DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + 1) - _in.elapseSinceArrival();
+ int delay = (iAmTheOnlyOne && !in.isTruncated()) ? 0 : DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + JmDNSImpl.getRandom().nextInt(DNSConstants.RESPONSE_MAX_WAIT_INTERVAL - DNSConstants.RESPONSE_MIN_WAIT_INTERVAL + 1) - in.elapseSinceArrival();
if (delay < 0)
{
delay = 0;
}
- if (logger.isLoggable(Level.FINEST))
- {
- logger.finest(this.getName() + "start() Responder chosen delay=" + delay);
- }
- if (!this.getDns().isCanceling() && !this.getDns().isCanceled())
- {
- timer.schedule(this, delay);
- }
+// logger.finest("start() Responder chosen delay=" + delay);
+ this.jmDNSImpl.schedule(this, delay);
}
- @Override
public void run()
{
- this.getDns().respondToQuery(_in);
+ synchronized (this.jmDNSImpl.getIoLock())
+ {
+ if (this.jmDNSImpl.getPlannedAnswer() == in)
+ {
+ this.jmDNSImpl.setPlannedAnswer(null);
+ }
- // We use these sets to prevent duplicate records
- Set<DNSQuestion> questions = new HashSet<DNSQuestion>();
- Set<DNSRecord> answers = new HashSet<DNSRecord>();
+ // We use these sets to prevent duplicate records
+ // FIXME - This should be moved into DNSOutgoing
+ HashSet questions = new HashSet();
+ HashSet answers = new HashSet();
- if (this.getDns().isAnnounced())
- {
- try
+
+ if (this.jmDNSImpl.getState() == DNSState.ANNOUNCED)
{
- // Answer questions
- for (DNSQuestion question : _in.getQuestions())
+ try
{
- if (logger.isLoggable(Level.FINER))
+ boolean isUnicast = (port != DNSConstants.MDNS_PORT);
+
+
+ // Answer questions
+ for (Iterator iterator = in.getQuestions().iterator(); iterator.hasNext();)
{
- logger.finer(this.getName() + "run() JmDNS responding to: " + question);
+ DNSEntry entry = (DNSEntry) iterator.next();
+ if (entry instanceof DNSQuestion)
+ {
+ DNSQuestion q = (DNSQuestion) entry;
+
+ // for unicast responses the question must be included
+ if (isUnicast)
+ {
+ //out.addQuestion(q);
+ questions.add(q);
+ }
+
+ int type = q.getType();
+ if (type == DNSConstants.TYPE_ANY || type == DNSConstants.TYPE_SRV)
+ { // I ama not sure of why there is a special case here [PJYF Oct 15 2004]
+ if (this.jmDNSImpl.getLocalHost().getName().equalsIgnoreCase(q.getName()))
+ {
+ // type = DNSConstants.TYPE_A;
+ DNSRecord answer = this.jmDNSImpl.getLocalHost().getDNS4AddressRecord();
+ if (answer != null)
+ {
+ answers.add(answer);
+ }
+ answer = this.jmDNSImpl.getLocalHost().getDNS6AddressRecord();
+ if (answer != null)
+ {
+ answers.add(answer);
+ }
+ type = DNSConstants.TYPE_IGNORE;
+ }
+ else
+ {
+ if (this.jmDNSImpl.getServiceTypes().containsKey(q.getName().toLowerCase()))
+ {
+ type = DNSConstants.TYPE_PTR;
+ }
+ }
+ }
+
+ switch (type)
+ {
+ case DNSConstants.TYPE_A:
+ {
+ // Answer a query for a domain name
+ //out = addAnswer( in, addr, port, out, host );
+ DNSRecord answer = this.jmDNSImpl.getLocalHost().getDNS4AddressRecord();
+ if (answer != null)
+ {
+ answers.add(answer);
+ }
+ break;
+ }
+ case DNSConstants.TYPE_AAAA:
+ {
+ // Answer a query for a domain name
+ DNSRecord answer = this.jmDNSImpl.getLocalHost().getDNS6AddressRecord();
+ if (answer != null)
+ {
+ answers.add(answer);
+ }
+ break;
+ }
+ case DNSConstants.TYPE_PTR:
+ {
+ // Answer a query for services of a given type
+
+ // find matching services
+ for (Iterator serviceIterator = this.jmDNSImpl.getServices().values().iterator(); serviceIterator.hasNext();)
+ {
+ ServiceInfoImpl info = (ServiceInfoImpl) serviceIterator.next();
+ if (info.getState() == DNSState.ANNOUNCED)
+ {
+ if (q.getName().equalsIgnoreCase(info.getType()))
+ {
+ DNSRecord answer = this.jmDNSImpl.getLocalHost().getDNS4AddressRecord();
+ if (answer != null)
+ {
+ answers.add(answer);
+ }
+ answer = this.jmDNSImpl.getLocalHost().getDNS6AddressRecord();
+ if (answer != null)
+ {
+ answers.add(answer);
+ }
+ answers.add(new DNSRecord.Pointer(info.getType(), DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.getQualifiedName()));
+ answers.add(new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL,
+ info.getPriority(), info.getWeight(), info.getPort(), this.jmDNSImpl.getLocalHost().getName()));
+ answers.add(new DNSRecord.Text(info.getQualifiedName(), DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL,
+ info.getText()));
+ }
+ }
+ }
+ if (q.getName().equalsIgnoreCase("_services" + DNSConstants.DNS_META_QUERY + "local."))
+ {
+ for (Iterator serviceTypeIterator = this.jmDNSImpl.getServiceTypes().values().iterator(); serviceTypeIterator.hasNext();)
+ {
+ answers.add(new DNSRecord.Pointer("_services" + DNSConstants.DNS_META_QUERY + "local.", DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, (String) serviceTypeIterator.next()));
+ }
+ }
+ break;
+ }
+ case DNSConstants.TYPE_SRV:
+ case DNSConstants.TYPE_ANY:
+ case DNSConstants.TYPE_TXT:
+ {
+ ServiceInfoImpl info = (ServiceInfoImpl) this.jmDNSImpl.getServices().get(q.getName().toLowerCase());
+ if (info != null && info.getState() == DNSState.ANNOUNCED)
+ {
+ DNSRecord answer = this.jmDNSImpl.getLocalHost().getDNS4AddressRecord();
+ if (answer != null)
+ {
+ answers.add(answer);
+ }
+ answer = this.jmDNSImpl.getLocalHost().getDNS6AddressRecord();
+ if (answer != null)
+ {
+ answers.add(answer);
+ }
+ answers.add(new DNSRecord.Pointer(info.getType(), DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.getQualifiedName()));
+ answers.add(new DNSRecord.Service(info.getQualifiedName(), DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL,
+ info.getPriority(), info.getWeight(), info.getPort(), this.jmDNSImpl.getLocalHost().getName()));
+ answers.add(new DNSRecord.Text(info.getQualifiedName(), DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN | DNSConstants.CLASS_UNIQUE, DNSConstants.DNS_TTL, info.getText()));
+ }
+ break;
+ }
+ default :
+ {
+ //System.out.println("JmDNSResponder.unhandled query:"+q);
+ break;
+ }
+ }
+ }
}
- // for unicast responses the question must be included
- if (_unicast)
+
+
+ // remove known answers, if the ttl is at least half of
+ // the correct value. (See Draft Cheshire chapter 7.1.).
+ for (Iterator i = in.getAnswers().iterator(); i.hasNext();)
{
- // out.addQuestion(q);
- questions.add(question);
+ DNSRecord knownAnswer = (DNSRecord) i.next();
+ if (knownAnswer.getTtl() > DNSConstants.DNS_TTL / 2 && answers.remove(knownAnswer))
+ {
+// logger.log(Level.FINER, "JmDNS Responder Known Answer Removed");
+ }
}
- question.addAnswers(this.getDns(), answers);
- }
- // remove known answers, if the ttl is at least half of the correct value. (See Draft Cheshire chapter 7.1.).
- long now = System.currentTimeMillis();
- for (DNSRecord knownAnswer : _in.getAnswers())
- {
- if (knownAnswer.isStale(now))
+ // responde if we have answers
+ if (answers.size() != 0)
{
- answers.remove(knownAnswer);
- if (logger.isLoggable(Level.FINER))
+// logger.finer("run() JmDNS responding");
+ DNSOutgoing out = null;
+ if (isUnicast)
+ {
+ out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, false);
+ }
+
+ for (Iterator i = questions.iterator(); i.hasNext();)
+ {
+ out.addQuestion((DNSQuestion) i.next());
+ }
+ for (Iterator i = answers.iterator(); i.hasNext();)
{
- logger.finer(this.getName() + "JmDNS Responder Known Answer Removed");
+ out = this.jmDNSImpl.addAnswer(in, addr, port, out, (DNSRecord) i.next());
}
+ this.jmDNSImpl.send(out);
}
+ this.cancel();
}
-
- // respond if we have answers
- if (answers.size() != 0)
+ catch (Throwable e)
{
- if (logger.isLoggable(Level.FINER))
- {
- logger.finer(this.getName() + "run() JmDNS responding");
- }
- DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, !_unicast, _in.getSenderUDPPayload());
- out.setId(_in.getId());
- for (DNSQuestion question : questions)
- {
- out = this.addQuestion(out, question);
- }
- for (DNSRecord answer : answers)
- {
- out = this.addAnswer(out, _in, answer);
- }
- if (!out.isEmpty())
- this.getDns().send(out);
+// logger.log(Level.WARNING, "run() exception ", e);
+ this.jmDNSImpl.close();
}
- // this.cancel();
- }
- catch (Throwable e)
- {
- logger.log(Level.WARNING, "run() exception ", e);
- this.getDns().close();
}
}
}

Back to the top