@Override public DNSIncoming clone() { DNSIncoming in = new DNSIncoming(this.getFlags(), this.getId(), this.isMulticast(), this._packet, this._receivedTime); in._senderUDPPayload = this._senderUDPPayload; in._questions.addAll(this._questions); in._answers.addAll(this._answers); in._authoritativeAnswers.addAll(this._authoritativeAnswers); in._additionals.addAll(this._additionals); return in; }
for (DNSRecord answer : in.getAllAnswers()) { conflictDetected |= answer.handleQuery(this, expirationTime); _plannedAnswer.append(in); } else { if (in.isTruncated()) { _plannedAnswer = in; for (DNSRecord answer : in.getAnswers()) { this.handleRecord(answer, now);
/** * Appends answers to this Incoming. * * @exception IllegalArgumentException * If not a query or if Truncated. */ void append(DNSIncoming that) { if (this.isQuery() && this.isTruncated() && that.isQuery()) { this._questions.addAll(that.getQuestions()); this._answers.addAll(that.getAnswers()); this._authoritativeAnswers.addAll(that.getAuthorities()); this._additionals.addAll(that.getAdditionals()); } else { throw new IllegalArgumentException(); } }
@Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append(isQuery() ? "dns[query," : "dns[response,"); if (_packet.getAddress() != null) { sb.append(_packet.getAddress().getHostAddress()); sb.append(_packet.getLength()); sb.append(", id=0x"); sb.append(Integer.toHexString(this.getId())); if (this.getFlags() != 0) { sb.append(", flags=0x"); sb.append(Integer.toHexString(this.getFlags())); if ((this.getFlags() & DNSConstants.FLAGS_QR_RESPONSE) != 0) { sb.append(":r"); if ((this.getFlags() & DNSConstants.FLAGS_AA) != 0) { sb.append(":aa"); if ((this.getFlags() & DNSConstants.FLAGS_TC) != 0) { sb.append(":tc"); if (this.getNumberOfQuestions() > 0) { sb.append(", questions="); sb.append(this.getNumberOfQuestions()); if (this.getNumberOfAnswers() > 0) { sb.append(", answers="); sb.append(this.getNumberOfAnswers());
try { for (DNSQuestion question : _in.getQuestions()) { if (logger.isLoggable(Level.FINER)) { logger.finer(this.getName() + "run() JmDNS responding to: " + question); for (DNSRecord knownAnswer : _in.getAnswers()) { if (knownAnswer.isStale(now)) { answers.remove(knownAnswer); 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) { if (question != null) {
@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); } }
DNSRecordType type = DNSRecordType.typeForIndex(_messageInputStream.readUnsignedShort()); if (type == DNSRecordType.TYPE_IGNORE) { logger.log(Level.SEVERE, "Could not find record type. domain: " + domain + "\n" + this.print(true)); logger.log(Level.SEVERE, "Could not find record class. domain: " + domain + " type: " + type + "\n" + this.print(true)); break; case TYPE_OPT: DNSResultCode extendedResultCode = DNSResultCode.resultCodeForFlags(this.getFlags(), ttl); int version = (ttl & 0x00ff0000) >> 16; if (version == 0) { logger.warning("Malformed OPT answer. Option code: Owner data: " + this._hexString(optiondata)); logger.fine("Unhandled Owner OPT version: " + ownerVersion + " sequence: " + ownerSequence + " MAC address: " + this._hexString(ownerPrimaryMacAddress) + (ownerWakeupMacAddress != ownerPrimaryMacAddress ? " wakeup MAC address: " + this._hexString(ownerWakeupMacAddress) : "") + (ownerPassword != null ? " password: " + this._hexString(ownerPassword) : "")); case UL: if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "There was an OPT answer. Option code: " + optionCode + " data: " + this._hexString(optiondata)); logger.log(Level.WARNING, "There was an OPT answer. Not currently handled. Option code: " + optionCodeInt + " data: " + this._hexString(optiondata)); break; default:
DNSIncoming msg = new DNSIncoming(packet); if (logger.isLoggable(Level.FINEST)) { logger.finest(this.getName() + ".run() JmDNS in:" + msg.print(true)); if (msg.isQuery()) { if (packet.getPort() != DNSConstants.MDNS_PORT) { this._jmDNSImpl.handleQuery(msg, packet.getAddress(), packet.getPort());
DNSIncoming msg = new DNSIncoming(packet); if (msg.isValidResponseCode()) { if (logger.isTraceEnabled()) { logger.trace( "{}.run() JmDNS in:{}", this.getName(), msg.print(true)); if (msg.isQuery()) { if (packet.getPort() != DNSConstants.MDNS_PORT) { this._jmDNSImpl.handleQuery(msg, packet.getAddress(), packet.getPort()); logger.debug("{}.run() JmDNS in message with error code: {}", this.getName(), msg.print(true));
/** * Add an answer to a question. Deal with the case when the outgoing packet overflows * * @param in * @param addr * @param port * @param out * @param rec * @return outgoing answer * @exception IOException */ public DNSOutgoing addAnswer(DNSIncoming in, InetAddress addr, int port, DNSOutgoing out, DNSRecord rec) throws IOException { DNSOutgoing newOut = out; if (newOut == null) { newOut = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, false, in.getSenderUDPPayload()); } try { newOut.addAnswer(in, rec); } catch (final IOException e) { newOut.setFlags(newOut.getFlags() | DNSConstants.FLAGS_TC); newOut.setId(in.getId()); send(newOut); newOut = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, false, in.getSenderUDPPayload()); newOut.addAnswer(in, rec); } return newOut; }
/** * Send an outgoing multicast DNS message. * * @param out * @exception IOException */ public void send(DNSOutgoing out) throws IOException { if (!out.isEmpty()) { byte[] message = out.data(); final DatagramPacket packet = new DatagramPacket(message, message.length, _group, DNSConstants.MDNS_PORT); if (logger.isLoggable(Level.FINEST)) { try { final DNSIncoming msg = new DNSIncoming(packet); if (logger.isLoggable(Level.FINEST)) { logger.finest("send(" + this.getName() + ") JmDNS out:" + msg.print(true)); } } catch (final IOException e) { logger.throwing(getClass().toString(), "send(" + this.getName() + ") - JmDNS can not parse what it sends!!!", e); } } final MulticastSocket ms = _socket; if (ms != null && !ms.isClosed()) { ms.send(packet); } } }
/** * True if this record is suppressed by the answers in a message. */ boolean suppressedBy(DNSIncoming msg) { try { for (DNSRecord answer : msg.getAllAnswers()) { if (suppressedBy(answer)) { return true; } } return false; } catch (ArrayIndexOutOfBoundsException e) { logger.warn("suppressedBy() message " + msg + " exception ", e); // msg.print(true); return false; } }
@Override public String toString() { StringBuilder buf = new StringBuilder(); buf.append(isQuery() ? "dns[query," : "dns[response,"); if (_packet.getAddress() != null) { buf.append(_packet.getAddress().getHostAddress()); buf.append(_packet.getLength()); buf.append(", id=0x"); buf.append(Integer.toHexString(this.getId())); if (this.getFlags() != 0) { buf.append(", flags=0x"); buf.append(Integer.toHexString(this.getFlags())); if ((this.getFlags() & DNSConstants.FLAGS_QR_RESPONSE) != 0) { buf.append(":r"); if ((this.getFlags() & DNSConstants.FLAGS_AA) != 0) { buf.append(":aa"); if ((this.getFlags() & DNSConstants.FLAGS_TC) != 0) { buf.append(":tc"); if (this.getNumberOfQuestions() > 0) { buf.append(", questions="); buf.append(this.getNumberOfQuestions()); if (this.getNumberOfAnswers() > 0) { buf.append(", answers="); buf.append(this.getNumberOfAnswers());
try { for (DNSQuestion question : _in.getQuestions()) { if (logger.isLoggable(Level.FINER)) { logger.finer(this.getName() + "run() JmDNS responding to: " + question); for (DNSRecord knownAnswer : _in.getAnswers()) { if (knownAnswer.isStale(now)) { answers.remove(knownAnswer); 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) { if (question != null) {
@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); } }
DNSRecordType type = DNSRecordType.typeForIndex(_messageInputStream.readUnsignedShort()); if (type == DNSRecordType.TYPE_IGNORE) { logger.log(Level.SEVERE, "Could not find record type. domain: " + domain + "\n" + this.print(true)); logger.log(Level.SEVERE, "Could not find record class. domain: " + domain + " type: " + type + "\n" + this.print(true)); break; case TYPE_OPT: DNSResultCode extendedResultCode = DNSResultCode.resultCodeForFlags(this.getFlags(), ttl); int version = (ttl & 0x00ff0000) >> 16; if (version == 0) { logger.warning("Malformed OPT answer. Option code: Owner data: " + this._hexString(optiondata)); logger.fine("Unhandled Owner OPT version: " + ownerVersion + " sequence: " + ownerSequence + " MAC address: " + this._hexString(ownerPrimaryMacAddress) + (ownerWakeupMacAddress != ownerPrimaryMacAddress ? " wakeup MAC address: " + this._hexString(ownerWakeupMacAddress) : "") + (ownerPassword != null ? " password: " + this._hexString(ownerPassword) : "")); case UL: if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "There was an OPT answer. Option code: " + optionCode + " data: " + this._hexString(optiondata)); logger.log(Level.WARNING, "There was an OPT answer. Not currently handled. Option code: " + optionCodeInt + " data: " + this._hexString(optiondata)); break; default:
DNSIncoming msg = new DNSIncoming(packet); if (logger.isLoggable(Level.FINEST)) { logger.finest(this.getName() + ".run() JmDNS in:" + msg.print(true)); if (msg.isQuery()) { if (packet.getPort() != DNSConstants.MDNS_PORT) { this._jmDNSImpl.handleQuery(msg, packet.getAddress(), packet.getPort());
/** * Add an answer to a question. Deal with the case when the outgoing packet overflows * * @param in * @param addr * @param port * @param out * @param rec * @return outgoing answer * @exception IOException */ public DNSOutgoing addAnswer(DNSIncoming in, InetAddress addr, int port, DNSOutgoing out, DNSRecord rec) throws IOException { DNSOutgoing newOut = out; if (newOut == null) { newOut = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, false, in.getSenderUDPPayload()); } try { newOut.addAnswer(in, rec); } catch (final IOException e) { newOut.setFlags(newOut.getFlags() | DNSConstants.FLAGS_TC); newOut.setId(in.getId()); send(newOut); newOut = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA, false, in.getSenderUDPPayload()); newOut.addAnswer(in, rec); } return newOut; }
/** * Send an outgoing multicast DNS message. * * @param out * @exception IOException */ public void send(DNSOutgoing out) throws IOException { if (!out.isEmpty()) { byte[] message = out.data(); final DatagramPacket packet = new DatagramPacket(message, message.length, _group, DNSConstants.MDNS_PORT); if (logger.isLoggable(Level.FINEST)) { try { final DNSIncoming msg = new DNSIncoming(packet); if (logger.isLoggable(Level.FINEST)) { logger.finest("send(" + this.getName() + ") JmDNS out:" + msg.print(true)); } } catch (final IOException e) { logger.throwing(getClass().toString(), "send(" + this.getName() + ") - JmDNS can not parse what it sends!!!", e); } } final MulticastSocket ms = _socket; if (ms != null && !ms.isClosed()) { ms.send(packet); } } }
/** * True if this record is suppressed by the answers in a message. */ boolean suppressedBy(DNSIncoming msg) { try { for (DNSRecord answer : msg.getAllAnswers()) { if (suppressedBy(answer)) { return true; } } return false; } catch (ArrayIndexOutOfBoundsException e) { logger.log(Level.WARNING, "suppressedBy() message " + msg + " exception ", e); // msg.print(true); return false; } }