Go to the documentation of this file.00001
00002
00003
00004
00005 package javax.jmdns.impl.tasks;
00006
00007 import java.util.HashSet;
00008 import java.util.Set;
00009 import java.util.Timer;
00010 import java.util.logging.Level;
00011 import java.util.logging.Logger;
00012
00013 import javax.jmdns.impl.DNSIncoming;
00014 import javax.jmdns.impl.DNSOutgoing;
00015 import javax.jmdns.impl.DNSQuestion;
00016 import javax.jmdns.impl.DNSRecord;
00017 import javax.jmdns.impl.JmDNSImpl;
00018 import javax.jmdns.impl.constants.DNSConstants;
00019
00023 public class Responder extends DNSTask {
00024 static Logger logger = Logger.getLogger(Responder.class.getName());
00025
00029 private final DNSIncoming _in;
00030
00034 private final boolean _unicast;
00035
00036 public Responder(JmDNSImpl jmDNSImpl, DNSIncoming in, int port) {
00037 super(jmDNSImpl);
00038 this._in = in;
00039 this._unicast = (port != DNSConstants.MDNS_PORT);
00040 }
00041
00042
00043
00044
00045
00046 @Override
00047 public String getName() {
00048 return "Responder(" + (this.getDns() != null ? this.getDns().getName() : "") + ")";
00049 }
00050
00051
00052
00053
00054
00055 @Override
00056 public String toString() {
00057 return super.toString() + " incomming: " + _in;
00058 }
00059
00060
00061
00062
00063
00064 @Override
00065 public void start(Timer timer) {
00066
00067
00068
00069
00070
00071
00072
00073 boolean iAmTheOnlyOne = true;
00074 for (DNSQuestion question : _in.getQuestions()) {
00075 if (logger.isLoggable(Level.FINEST)) {
00076 logger.finest(this.getName() + "start() question=" + question);
00077 }
00078 iAmTheOnlyOne = question.iAmTheOnlyOne(this.getDns());
00079 if (!iAmTheOnlyOne) {
00080 break;
00081 }
00082 }
00083 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();
00084 if (delay < 0) {
00085 delay = 0;
00086 }
00087 if (logger.isLoggable(Level.FINEST)) {
00088 logger.finest(this.getName() + "start() Responder chosen delay=" + delay);
00089 }
00090 if (!this.getDns().isCanceling() && !this.getDns().isCanceled()) {
00091 timer.schedule(this, delay);
00092 }
00093 }
00094
00095 @Override
00096 public void run() {
00097 this.getDns().respondToQuery(_in);
00098
00099
00100 Set<DNSQuestion> questions = new HashSet<DNSQuestion>();
00101 Set<DNSRecord> answers = new HashSet<DNSRecord>();
00102
00103 if (this.getDns().isAnnounced()) {
00104 try {
00105
00106 for (DNSQuestion question : _in.getQuestions()) {
00107 if (logger.isLoggable(Level.FINER)) {
00108 logger.finer(this.getName() + "run() JmDNS responding to: " + question);
00109 }
00110
00111 if (_unicast) {
00112
00113 questions.add(question);
00114 }
00115
00116 question.addAnswers(this.getDns(), answers);
00117 }
00118
00119
00120 long now = System.currentTimeMillis();
00121 for (DNSRecord knownAnswer : _in.getAnswers()) {
00122 if (knownAnswer.isStale(now)) {
00123 answers.remove(knownAnswer);
00124 if (logger.isLoggable(Level.FINER)) {
00125 logger.finer(this.getName() + "JmDNS Responder Known Answer Removed");
00126 }
00127 }
00128 }
00129
00130
00131 if (!answers.isEmpty()) {
00132 if (logger.isLoggable(Level.FINER)) {
00133 logger.finer(this.getName() + "run() JmDNS responding");
00134 }
00135 DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, !_unicast, _in.getSenderUDPPayload());
00136 out.setId(_in.getId());
00137 for (DNSQuestion question : questions) {
00138 if (question != null) {
00139 out = this.addQuestion(out, question);
00140 }
00141 }
00142 for (DNSRecord answer : answers) {
00143 if (answer != null) {
00144 out = this.addAnswer(out, _in, answer);
00145
00146 }
00147 }
00148 if (!out.isEmpty()) this.getDns().send(out);
00149 }
00150
00151 } catch (Throwable e) {
00152 logger.log(Level.WARNING, this.getName() + "run() exception ", e);
00153 this.getDns().close();
00154 }
00155 }
00156 }
00157 }