@Override public Message send(Message query) throws IOException { final String HOSTNAME = "localhost."; if (query.getQuestion().getName().toString().equals(Constants.TEST_QUERY)) { Record question = Record.newRecord(query.getQuestion().getName(), Type.SRV, DClass.IN); Message queryMessage = Message.newQuery(question); Message result = new Message(); result.setHeader(queryMessage.getHeader()); result.addRecord(question, Section.QUESTION); result.addRecord(new SRVRecord(query.getQuestion().getName(), DClass.IN, 1, 1, 1, Constants.NODE_0_TRANSPORT_TCP_PORT, Name.fromString(HOSTNAME)), Section.ANSWER); result.addRecord(new SRVRecord(query.getQuestion().getName(), DClass.IN, 1, 1, 1, Constants.NODE_1_TRANSPORT_TCP_PORT, Name.fromString(HOSTNAME)), Section.ANSWER); result.addRecord(new SRVRecord(query.getQuestion().getName(), DClass.IN, 1, 1, 1, Constants.NODE_2_TRANSPORT_TCP_PORT, Name.fromString(HOSTNAME)), Section.ANSWER); result.addRecord(new SRVRecord(query.getQuestion().getName(), DClass.IN, 1, 1, 1, Constants.NODE_3_TRANSPORT_TCP_PORT, Name.fromString(HOSTNAME)), Section.ANSWER); result.addRecord(new SRVRecord(query.getQuestion().getName(), DClass.IN, 1, 1, 1, Constants.NODE_4_TRANSPORT_TCP_PORT, Name.fromString(HOSTNAME)), Section.ANSWER); return result; } if (query.getQuestion().getName().toString().equals(HOSTNAME)) { Record question = Record.newRecord(query.getQuestion().getName(), Type.A, DClass.IN); Message queryMessage = Message.newQuery(question); Message result = new Message(); result.setHeader(queryMessage.getHeader()); result.addRecord(question, Section.QUESTION); result.addRecord(new ARecord(query.getQuestion().getName(), DClass.IN, 1, InetAddress.getLoopbackAddress()), Section.ANSWER); return result; } throw new IllegalArgumentException("Unknown test query: " + query.getQuestion().getName().toString()); } };
@Test public void testBlockedDnsQuery() throws Exception { Message message = Message.newQuery(new ARecord(new Name("blocked.example.com."), 0x01, 3600, .payloadBuilder( new UnknownPacket.Builder() .rawData(message.toWire()) ); assertTrue(mockEventLoop.lastResponse.getPayload() instanceof UdpPacket); Message responseMsg = new Message(mockEventLoop.lastResponse.getPayload().getPayload().getRawData()); assertEquals(NOERROR, responseMsg.getHeader().getRcode()); assertArrayEquals(new Record[] {}, responseMsg.getSectionArray(Section.ANSWER)); assertNotEquals(0, responseMsg.getSectionArray(Section.AUTHORITY).length); assertTrue(responseMsg.getSectionArray(Section.AUTHORITY)[0] instanceof SOARecord); assertTrue(responseMsg.getSectionArray(Section.AUTHORITY)[0].getTTL() > 0);
Message dnsMsg; try { dnsMsg = new Message(dnsRawData); } catch (IOException e) { Log.i(TAG, "handleDnsRequest: Discarding non-DNS or invalid packet", e); return; if (dnsMsg.getQuestion() == null) { Log.i(TAG, "handleDnsRequest: Discarding DNS packet with no query " + dnsMsg); return; String dnsQueryName = dnsMsg.getQuestion().getName().toString(true); if (!ruleDatabase.isBlocked(dnsQueryName.toLowerCase(Locale.ENGLISH))) { Log.i(TAG, "handleDnsRequest: DNS Name " + dnsQueryName + " Allowed, sending to " + destAddr); } else { Log.i(TAG, "handleDnsRequest: DNS Name " + dnsQueryName + " Blocked!"); dnsMsg.getHeader().setFlag(Flags.QR); dnsMsg.getHeader().setRcode(Rcode.NOERROR); dnsMsg.addRecord(NEGATIVE_CACHE_SOA_RECORD, Section.AUTHORITY); handleDnsResponse(parsedPacket, dnsMsg.toWire());
byte[] buildErrorMessage(final Header header, final int rcode, final Record question) { final Message response = new Message(); response.setHeader(header); for (int i = 0; i < 4; i++) response.removeAllRecords(i); if (rcode == Rcode.SERVFAIL) response.addRecord(question, Section.QUESTION); header.setRcode(rcode); return response.toWire(); }
Record[] assertDNSQueryNotNull(String lookup, int type, int answerCount) throws IOException { Name name = Name.fromString(lookup); Record question = Record.newRecord(name, type, DClass.IN); Message query = Message.newQuery(question); OPTRecord optRecord = new OPTRecord(4096, 0, 0, Flags.DO, null); query.addRecord(optRecord, Section.ADDITIONAL); byte[] responseBytes = getRegistryDNS().generateReply(query, null); Message response = new Message(responseBytes); assertEquals("not successful", Rcode.NOERROR, response.getRcode()); assertNotNull("Null response", response); assertEquals("Questions do not match", query.getQuestion(), response.getQuestion()); Record[] recs = response.getSectionArray(Section.ANSWER); assertEquals(answerCount, recs.length); assertEquals(recs[0].getType(), type); return recs; }
private void sendQuery() throws IOException { Record question = Record.newRecord(zname, qtype, dclass); Message query = new Message(); query.getHeader().setOpcode(Opcode.QUERY); query.addRecord(question, Section.QUESTION); if (qtype == Type.IXFR) { Record soa = new SOARecord(zname, dclass, 0, Name.root, Name.root, ixfr_serial, 0, 0, 0, 0); query.addRecord(soa, Section.AUTHORITY); } if (tsig != null) { tsig.apply(query, null); verifier = new TSIG.StreamVerifier(tsig, query.getTSIG()); } byte [] out = query.toWire(Message.MAXLENGTH); client.send(out); }
/** * Create a query to forward to the primary DNS server (if configured). * NOTE: Experimental * * @param query the inbound query. * @return the query to forward to the primary server. * @throws NameTooLongException * @throws TextParseException if query creation fails. */ private Message createPrimaryQuery(Message query) throws NameTooLongException, TextParseException { Name name = query.getQuestion().getName(); if (name.labels() > 0 && name.labels() <= 2) { // short relative or absolute name. this code may not be necessary - // OS resolution utilities probably append the search paths defined // in resolv.conf prior to the lookup int id = query.getHeader().getID(); String queryName = name.getLabelString(0); Name qualifiedName = Name.concatenate(Name.fromString(queryName), Name.fromString(domainName)); LOG.info("Received query {}. Forwarding query {}", name, qualifiedName); Record question = Record.newRecord(qualifiedName, query.getQuestion().getType(), query.getQuestion().getDClass()); query = Message.newQuery(question); query.getHeader().setID(id); } return query; }
private Message sendAXFR(Message query) throws IOException { Name qname = query.getQuestion().getName(); ZoneTransferIn xfrin = ZoneTransferIn.newAXFR(qname, address, tsig); xfrin.setTimeout((int)(getTimeout() / 1000)); xfrin.setLocalAddress(localAddress); try { xfrin.run(); } catch (ZoneTransferException e) { throw new WireParseException(e.getMessage()); } List records = xfrin.getAXFR(); Message response = new Message(query.getHeader().getID()); response.getHeader().setFlag(Flags.AA); response.getHeader().setFlag(Flags.QR); response.addRecord(query.getQuestion(), Section.QUESTION); Iterator it = records.iterator(); while (it.hasNext()) response.addRecord((Record)it.next(), Section.ANSWER); return response; }
@Test public void testContainerRegistrationPersistanceAbsent() throws Exception { ServiceRecord record = marshal.fromBytes("somepath", CONTAINER_RECORD_YARN_PERSISTANCE_ABSENT.getBytes()); registryDNS.register( "/registry/users/root/services/org-apache-slider/test1/components/" + "ctr-e50-1451931954322-0016-01-000003", record); Name name = Name.fromString("ctr-e50-1451931954322-0016-01-000002.dev.test."); Record question = Record.newRecord(name, Type.A, DClass.IN); Message query = Message.newQuery(question); byte[] responseBytes = registryDNS.generateReply(query, null); Message response = new Message(responseBytes); assertEquals("Excepting NXDOMAIN as Record must not have regsisterd wrong", Rcode.NXDOMAIN, response.getRcode()); }
byte[] generateReply(final Message query, final byte[] in, final int length, final Socket s) { final Header header = query.getHeader(); int maxLength; int flags = 0; return errorMessage(query, Rcode.NOTIMP); final Record queryRecord = query.getQuestion(); final TSIGRecord queryTSIG = query.getTSIG(); TSIG tsig = null; if (queryTSIG != null) { final OPTRecord queryOPT = query.getOPT(); final Message response = new Message(query.getHeader().getID()); response.getHeader().setFlag(Flags.QR); if (query.getHeader().getFlag(Flags.RD)) { response.getHeader().setFlag(Flags.RD); response.addRecord(queryRecord, Section.QUESTION); final int optflags = (flags == FLAG_DNSSECOK) ? ExtendedFlags.DO : 0; final OPTRecord opt = new OPTRecord((short) 4096, rcode, (byte) 0, optflags); response.addRecord(opt, Section.ADDITIONAL); response.setTSIG(tsig, Rcode.NOERROR, queryTSIG); return response.toWire(maxLength);
private Message makeQuery(DNSRequest request, int id) throws TextParseException { Name name = Name.fromString(request.getHostname(), Name.root); int type; switch (request.getRecordType()) { case DNSRequest.A: type = Type.A; break; case DNSRequest.AAAA: type = Type.AAAA; break; case DNSRequest.MX: type = Type.MX; break; case DNSRequest.PTR: type = Type.PTR; break; case DNSRequest.SPF: type = Type.SPF; break; case DNSRequest.TXT: type = Type.TXT; break; default: throw new UnsupportedOperationException("Unknown query type: "+request.getRecordType()); } Record question = Record.newRecord(name, type, DClass.ANY); Message query = Message.newQuery(question); query.getHeader().setID(id); return query; } }
protected Message convertUpdateToQueryResponse(final Message update) { Message m = new Message(); Header h = m.getHeader(); h.setOpcode(Opcode.QUERY); h.setFlag(Flags.AA); h.setFlag(Flags.QR); Record[] records = update.getSectionArray(Section.UPDATE); for (int index = 0; index < records.length; index++ ) { m.addRecord(records[index], Section.ANSWER); } records = update.getSectionArray(Section.ADDITIONAL); for (int index = 0; index < records.length; index++ ) { m.addRecord(records[index], Section.ADDITIONAL); } return m; }
protected byte[] getMessageBytes(String data) { Message msg = new Message(); String recs[] = data.split(NL); for (String rec : recs) { if (rec.length() <= 3) { Header head = msg.getHeader(); int val = Integer.parseInt(rec.trim()); if (val < 0) { head.unsetFlag(-val); } else { head.setFlag(val); } msg.setHeader(head); } else { msg.addRecord(getRecord(rec.trim()), Section.QUESTION); } } return msg.toWire(); }
/** * Processes a DNS error condition and creates an appropriate DNS response. * @param request The original DNS request. * @param error The error condition that occured. * @return A response to the DNS request. */ protected Message processError(Message request, DNSError<?> error) { Message errorResponse = null; try { Header respHeader = new Header(request.toWire()); Message response = new Message(); response.setHeader(respHeader); for (int i = 0; i < 4; i++) response.removeAllRecords(i); response.addRecord(request.getQuestion(), Section.QUESTION); response.getHeader().setFlag(Flags.QR); if (request.getHeader().getFlag(Flags.RD)) response.getHeader().setFlag(Flags.RD); respHeader.setRcode(Integer.parseInt(error.getError().toString())); return response; } catch (IOException e) {} return errorResponse; }
try { final DataOutputStream dataOut = new DataOutputStream(s.getOutputStream()); int id = query.getHeader().getID(); while (it.hasNext()) { final RRset rrset = it.next(); final Message response = new Message(id); final Header header = response.getHeader(); header.setFlag(Flags.QR); header.setFlag(Flags.AA); if (tsig != null) { tsig.applyStream(response, qtsig, first); qtsig = response.getTSIG(); final byte[] out = response.toWire(); dataOut.writeShort(out.length); dataOut.write(out);
byte [] in = client.recv(); Message response = parseMessage(in); if (response.getHeader().getRcode() == Rcode.NOERROR && verifier != null) TSIGRecord tsigrec = response.getTSIG(); Record [] answers = response.getSectionArray(Section.ANSWER); int rcode = response.getRcode(); if (rcode != Rcode.NOERROR) { if (qtype == Type.IXFR && Record question = response.getQuestion(); if (question != null && question.getType() != qtype) { fail("invalid question section"); !response.isVerified()) fail("last message must be signed");
void addRRset(final Name name, final Message response, final RRset rrset, final int section, final int flags) { for (int s = 1; s <= section; s++) { if (response.findRRset(name, rrset.getType(), s)) return; } if ((flags & FLAG_SIGONLY) == 0) { @SuppressWarnings("unchecked") final Iterator<Record> it = rrset.rrs(); while (it.hasNext()) { final Record r = it.next(); if (r.getName().isWild() && !name.isWild()) { response.addRecord(r.withName(name), section); } else { response.addRecord(r, section); } } } if ((flags & (FLAG_SIGONLY | FLAG_DNSSECOK)) != 0) { @SuppressWarnings("unchecked") final Iterator<Record> it = rrset.sigs(); while (it.hasNext()) { final Record r = it.next(); if (r.getName().isWild() && !name.isWild()) { response.addRecord(r.withName(name), section); } else { response.addRecord(r, section); } } } }
/** * Resolve an IP address to a host name. * * @param hostIp dotted decimal IPv4 address. * @return name if resolved, or the address. * @throws IOException from infrastructure. */ public static String reverseDns(String hostIp) throws IOException { Resolver res = new ExtendedResolver(); // set the timeout, defaults to 200 milliseconds int timeout = ConfigurationManager.getIntProperty("usage-statistics", "resolver.timeout", 200); res.setTimeout(0, timeout); Name name = ReverseMap.fromAddress(hostIp); int type = Type.PTR; int dclass = DClass.IN; Record rec = Record.newRecord(name, type, dclass); Message query = Message.newQuery(rec); Message response = res.send(query); Record[] answers = response.getSectionArray(Section.ANSWER); if (answers.length == 0) { return hostIp; } else { return answers[0].rdataToString(); } }
/** * Asynchronously sends a message to a single server, registering a listener * to receive a callback on success or exception. Multiple asynchronous * lookups can be performed in parallel. Since the callback may be invoked * before the function returns, external synchronization is necessary. * @param query The query to send * @param listener The object containing the callbacks. * @return An identifier, which is also a parameter in the callback */ public Object sendAsync(final Message query, final ResolverListener listener) { final Object id; synchronized (this) { id = new Integer(uniqueID++); } Record question = query.getQuestion(); String qname; if (question != null) qname = question.getName().toString(); else qname = "(none)"; String name = this.getClass() + ": " + qname; Thread thread = new ResolveThread(this, query, id, listener); thread.setName(name); thread.setDaemon(true); thread.start(); return id; }