/** * Add a listener for a question. The listener will receive updates of answers to the question as they arrive, or from the cache if they are already available. * * @param listener * DSN listener * @param question * DNS query */ public void addListener(DNSListener listener, DNSQuestion question) { final long now = System.currentTimeMillis(); // add the new listener _listeners.add(listener); // report existing matched records if (question != null) { for (DNSEntry dnsEntry : this.getCache().getDNSEntryList(question.getName().toLowerCase())) { if (question.answeredBy(dnsEntry) && !dnsEntry.isExpired(now)) { listener.updateRecord(this.getCache(), now, dnsEntry); } } } }
void writeQuestion(DNSQuestion question) { writeName(question.getName()); writeShort(question.getRecordType().indexValue()); writeShort(question.getRecordClass().indexValue()); }
/** * 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()); }
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()) || this.getName().equalsIgnoreCase(info.getTypeWithSubtype())) { answers.addAll(jmDNSImpl.getLocalHost().answers(this.getRecordClass(), DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL)); answers.addAll(info.answers(this.getRecordClass(), DNSRecordClass.UNIQUE, DNSConstants.DNS_TTL, jmDNSImpl.getLocalHost())); } logger.debug("{} DNSQuestion({}).addAnswersForServiceInfo(): info: {}\n{}", jmDNSImpl.getName(), this.getName(), info, answers); } }
@Override protected DNSOutgoing addQuestions(DNSOutgoing out) throws IOException { DNSOutgoing newOut = out; newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_type, DNSRecordType.TYPE_PTR, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE)); // newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_type, DNSRecordType.TYPE_SRV, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE)); return newOut; }
@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 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. // 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": // We respond after 20-120 ms if the query is truncated. boolean iAmTheOnlyOne = true; for (DNSQuestion question : _in.getQuestions()) { if (logger.isLoggable(Level.FINEST)) { logger.finest(this.getName() + "start() question=" + question); } iAmTheOnlyOne = question.iAmTheOnlyOne(this.getDns()); 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(); 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); } }
return new Text(name, type, recordClass, unique); default: return new DNSQuestion(name, type, recordClass, unique);
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); } } }
@Override protected DNSOutgoing addQuestions(DNSOutgoing out) throws IOException { DNSOutgoing newOut = out; newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_type, DNSRecordType.TYPE_PTR, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE)); // newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_type, DNSRecordType.TYPE_SRV, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE)); return newOut; }
@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 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. // 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": // We respond after 20-120 ms if the query is truncated. boolean iAmTheOnlyOne = true; for (DNSQuestion question : _in.getQuestions()) { if (logger.isLoggable(Level.FINEST)) { logger.finest(this.getName() + "start() question=" + question); } iAmTheOnlyOne = question.iAmTheOnlyOne(this.getDns()); 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(); 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); } }
return new Text(name, type, recordClass, unique); default: return new DNSQuestion(name, type, recordClass, unique);
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); } } }
/** * 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()); }
void writeQuestion(DNSQuestion question) { writeName(question.getName()); writeShort(question.getRecordType().indexValue()); writeShort(question.getRecordClass().indexValue()); }
@Override protected DNSOutgoing addQuestions(DNSOutgoing out) throws IOException { DNSOutgoing newOut = out; newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_type, DNSRecordType.TYPE_PTR, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE)); // newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_type, DNSRecordType.TYPE_SRV, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE)); return newOut; }
/** * Add a listener for a question. The listener will receive updates of answers to the question as they arrive, or from the cache if they are already available. * * @param listener * DSN listener * @param question * DNS query */ public void addListener(DNSListener listener, DNSQuestion question) { final long now = System.currentTimeMillis(); // add the new listener _listeners.add(listener); // report existing matched records if (question != null) { for (DNSEntry dnsEntry : this.getCache().getDNSEntryList(question.getName().toLowerCase())) { if (question.answeredBy(dnsEntry) && !dnsEntry.isExpired(now)) { listener.updateRecord(this.getCache(), now, dnsEntry); } } } }
@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 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. // 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": // We respond after 20-120 ms if the query is truncated. boolean iAmTheOnlyOne = true; for (DNSQuestion question : _in.getQuestions()) { if (logger.isLoggable(Level.FINEST)) { logger.finest(this.getName() + "start() question=" + question); } iAmTheOnlyOne = question.iAmTheOnlyOne(this.getDns()); 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(); 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); } }