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; }
@Test public void itLogsServerErrors() throws Exception { header.setRcode(Rcode.REFUSED); Name name = Name.fromString("John Wayne."); Record question = Record.newRecord(name, 65530, 43210); Message query = Message.newQuery(question); Message response = mock(Message.class); when(response.getHeader()).thenReturn(header); when(response.getSectionArray(Section.ANSWER)).thenReturn(null); when(response.getQuestion()).thenReturn(question); when(nameServer.query( any(Message.class), any(InetAddress.class), any(DNSAccessRecord.Builder.class))) .thenThrow(new RuntimeException("Aw snap!")); FakeAbstractProtocol abstractProtocol = new FakeAbstractProtocol(client, query.toWire()); abstractProtocol.setNameServer(nameServer); abstractProtocol.run(); verify(accessLogger) .info( "144140678.000 qtype=DNS chi=192.168.23.45 ttms=345.123 xn=65535 fqdn=John\\032Wayne. type=TYPE65530 class=CLASS43210 rcode=SERVFAIL rtype=- rloc=\"-\" rdtl=- rerr=\"Server Error:RuntimeException:Aw snap!\" ttl=\"-\" ans=\"-\""); }
/* * Look for SOA records corresponding to the request * TODO: Add cache coherency to SOA records? */ protected synchronized Record checkForSoaRecord(String questionName) { if (!questionName.endsWith(".")) questionName += "."; if (soaRecords == null) { DnsRecord[] getRecs = null; // load all SOA records... try { getRecs = proxy.getDNSByType(Type.SOA); if (getRecs == null || getRecs.length == 0) soaRecords = Collections.emptyMap(); else { soaRecords = new HashMap<String, Record>(); for (DnsRecord rec : getRecs) { Record newRec = Record.newRecord( Name.fromString(rec.getName()), Type.SOA, rec.getDclass(), rec.getTtl(), rec.getData()); soaRecords.put(newRec.getName().toString(), newRec); } } } catch (Exception e) { LOGGER.error("Failed to load SOA records from config service."); } } Record retVal = null; if (soaRecords.size() > 0) { // look for the record by question name retVal = soaRecords.get(questionName); if (retVal == null) { // start taking apart the question name . by . int index = -1; while ((index = questionName.indexOf(".")) > 0 && index < (questionName.length() - 1)) { questionName = questionName.substring(index + 1); retVal = soaRecords.get(questionName); if (retVal != null) break; } } } return retVal; }
private void sendQuery() { Header queryHeader = new Header(); // If we set the RA (Recursion Available) flag and our message ID to 0 // then the packet matches the real mDNS query packet as displayed in Wireshark queryHeader.setFlag(org.xbill.DNS.Flags.RA); queryHeader.setID(0); Record question = null; try { // We need to create our "Question" DNS query that is a pointer record to // the mDNS Query "Name" question = Record.newRecord(new Name(NvmDNS.MDNS_QUERY), Type.PTR, DClass.IN); } catch (TextParseException e) { Log.e("NvmDNS Query", e.getMessage()); return; } // We combine our header and our question into a single message Message query = new Message(); query.setHeader(queryHeader); query.addRecord(question, Section.QUESTION); // Convert the message into Network Byte Order byte[] wireQuery = query.toWire(); Log.i("NvmDNS Query", query.toString()); // Convert our byte array into a Packet DatagramPacket transmitPacket = new DatagramPacket(wireQuery, wireQuery.length); transmitPacket.setAddress(NvmDNS.MDNS_MULTICAST_ADDRESS); transmitPacket.setPort(NvmDNS.MDNS_PORT); // And (attempt) to send the packet try { Log.d("NvmDNS Query", "Blocking on this.nvstream_socket.send(transmitPacket)"); this.socket.send(transmitPacket); Log.d("NvmDNS Query", "Passed this.nvstream_socket.send(transmitPacket)"); } catch (IOException e) { Log.e("NvmDNS Query", "There was an error sending the DNS query."); Log.e("NvmDNS Query", e.getMessage()); } }
@Test public void itLogsARecordQueries() throws Exception { header.setRcode(Rcode.NOERROR); Name name = Name.fromString("www.example.com."); Record question = Record.newRecord(name, Type.A, DClass.IN, 0L); Message query = Message.newQuery(question); query.getHeader().getRcode(); byte[] queryBytes = query.toWire(); whenNew(Message.class).withArguments(queryBytes).thenReturn(query); InetAddress resolvedAddress = Inet4Address.getByName("192.168.8.9"); Record answer = new ARecord(name, DClass.IN, 3600L, resolvedAddress); Record[] answers = new Record[] {answer}; Message response = mock(Message.class); when(response.getHeader()).thenReturn(header); when(response.getSectionArray(Section.ANSWER)).thenReturn(answers); when(response.getQuestion()).thenReturn(question); InetAddress client = Inet4Address.getByName("192.168.23.45"); when(nameServer.query( any(Message.class), any(InetAddress.class), any(DNSAccessRecord.Builder.class))) .thenReturn(response); FakeAbstractProtocol abstractProtocol = new FakeAbstractProtocol(client, queryBytes); abstractProtocol.setNameServer(nameServer); abstractProtocol.run(); verify(accessLogger) .info( "144140678.000 qtype=DNS chi=192.168.23.45 ttms=345.123 xn=65535 fqdn=www.example.com. type=A class=IN rcode=NOERROR rtype=- rloc=\"-\" rdtl=- rerr=\"-\" ttl=\"3600\" ans=\"192.168.8.9\""); }
protected Collection<Record> processGenericANYRecordRequest(String name) throws DNSException { DnsRecord records[]; try { records = proxy.getDNSByNameAndType(name, Type.ANY); } catch (Exception e) { throw new DNSException( DNSError.newError(Rcode.SERVFAIL), "DNS service proxy call for DNS records failed: " + e.getMessage(), e); } if (records == null || records.length == 0) return null; Collection<Record> retVal = new ArrayList<Record>(); try { for (DnsRecord record : records) { Record rec = Record.newRecord( Name.fromString(record.getName()), record.getType(), record.getDclass(), record.getTtl(), record.getData()); retVal.add(rec); } } catch (Exception e) { throw new DNSException( DNSError.newError(Rcode.SERVFAIL), "Failure while parsing generic record data: " + e.getMessage(), e); } return retVal; }
/* * converts a configuration service DnsRecord to a dnsjava Record */ private Record toRecord(DnsRecord rec) { return Record.newRecord( nameFromString(rec.getName()), rec.getType(), rec.getDclass(), rec.getTtl(), rec.getData()); }