Skip to content

Commit

Permalink
Cleanup of examples and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
ibauersachs committed Jan 19, 2020
1 parent 8fc771a commit 02d2816
Show file tree
Hide file tree
Showing 5 changed files with 286 additions and 111 deletions.
19 changes: 11 additions & 8 deletions EXAMPLES.md
@@ -1,6 +1,6 @@
# dnsjava examples
# dnsjava Examples

All of these examples are code fragments. Code using these fragments should
All of these examples are code fragments. Code using these fragments should
check exceptions when appropriate, and should:

```java
Expand All @@ -16,8 +16,8 @@ InetAddress addr = Address.getByName("www.dnsjava.org");
## Get the MX target and preference of a name

```java
Record [] records = new Lookup("gmail.com", Type.MX).run();
for (int i = 0; i < records.length; i++) {
Record[] records = new Lookup("gmail.com", Type.MX).run();
for (int i = 0; i < records.length; i++) {
MXRecord mx = (MXRecord) records[i];
System.out.println("Host " + mx.getTarget() + " has preference " + mx.getPriority());
}
Expand All @@ -29,17 +29,19 @@ for (int i = 0; i &lt; records.length; i++) {
Lookup l = new Lookup("version.bind.", Type.TXT, DClass.CH);
l.setResolver(new SimpleResolver(args[0]));
l.run();
if (l.getResult() == Lookup.SUCCESSFUL)
if (l.getResult() == Lookup.SUCCESSFUL) {
System.out.println(l.getAnswers()[0].rdataToString());
}
```

## Transfer a zone from a server and print it

```java
ZoneTransferIn xfr = ZoneTransferIn.newAXFR(new Name("."), "192.5.5.241", null);
ZoneTransferIn xfr = ZoneTransferIn.newAXFR(Name.root, "192.5.5.241", null);
List records = xfr.run();
for (Iterator it = records.iterator(); it.hasNext(); )
for (Iterator it = records.iterator(); it.hasNext();) {
System.out.println(it.next());
}
```

## Use DNS dynamic update to set the address of a host to a value specified on the command line
Expand Down Expand Up @@ -73,6 +75,7 @@ System.out.println(n2.equals(n)); // True
// www
// dnsjava
// org
for (int i = 0; i &lt; n.labels(); i++)
for (int i = 0; i < n.labels(); i++) {
System.out.println(n.getLabelString(i));
}
```
237 changes: 196 additions & 41 deletions README.md
Expand Up @@ -7,18 +7,18 @@

## Overview

dnsjava is an implementation of DNS in Java. It supports all defined record
types (including the DNSSEC types), and unknown types. It can be used for
queries, zone transfers, and dynamic updates. It includes a cache which can be
used by clients, and an authoritative only server. It supports TSIG
authenticated messages, partial DNSSEC verification, and EDNS0. It is fully
thread safe. It can be used to replace the native DNS support in Java.

dnsjava was started as an excuse to learn Java. It was useful for testing new
features in BIND without rewriting the C resolver. It was then cleaned up and
dnsjava is an implementation of DNS in Java. It supports almost all defined record
types (including the DNSSEC types), and unknown types. It can be used for
queries, zone transfers, and dynamic updates. It includes a cache which can be
used by clients, and an authoritative only server. It supports TSIG
authenticated messages, partial DNSSEC verification, and EDNS0. It is fully
thread safe.

dnsjava was started as an excuse to learn Java. It was useful for testing new
features in BIND without rewriting the C resolver. It was then cleaned up and
extended in order to be used as a testing framework for DNS interoperability
testing. The high level API and caching resolver were added to make it useful
to a wider audience. The authoritative only server was added as proof of
testing. The high level API and caching resolver were added to make it useful
to a wider audience. The authoritative only server was added as proof of
concept.

## dnsjava on Github
Expand All @@ -30,66 +30,215 @@ As of 2019-05-15, Github is
[officially](https://sourceforge.net/p/dnsjava/mailman/message/36666800/)
the new home of dnsjava.

Please use the Github [issue tracker](https://github.com/dnsjava/dnsjava/issues) and send - well tested - pull
requests. The
Please use the Github [issue tracker](https://github.com/dnsjava/dnsjava/issues)
and send - well tested - pull requests. The
[dnsjava-users@lists.sourceforge.net](mailto:dnsjava-users@lists.sourceforge.net)
mailing list still exists.

## Author

- Brian Wellington (@bwelling), March 12, 2004
- Various contributors, see [Changelog](Changelog)

## Getting started

Run `mvn package` from the toplevel directory to build dnsjava. JDK 1.4
or higher is required.

### Replacing the standard Java DNS functionality:

Java versions from 1.4 to 1.8 can load DNS service providers at runtime. The
### Config options
Some settings of dnsjava can be configured via
[system properties](https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html):

<table>
<thead>
<tr>
<th rowspan="2">Property</th>
<th>Type</th>
<th>Default</th>
<th>Example</th>
</tr>
<tr>
<th colspan="3">Explanation</th>
</tr>
</thead>
<tbody class="rich-diff-level-one">
<tr>
<td rowspan="2">dns.server</td>
<td>String</td>
<td>-</td>
<td>8.8.8.8,[2001:4860:4860::8888]:853,dns.google</td>
</tr>
<tr>
<td colspan="3">DNS server(s) to use for resolving. Comma separated list. Can be IPv4/IPv6 addresses or hostnames (which are resolved using Java's built in DNS support).</td>
</tr>
<tr>
<td rowspan="2">dns.search</td>
<td>String</td>
<td>-</td>
<td>ds.example.com,example.com</td>
</tr>
<tr>
<td colspan="3">Comma separated list of DNS search paths.</td>
</tr>
<tr>
<td rowspan="2">dns.ndots</td>
<td>Integer</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td colspan="3">Sets a threshold for the number of dots which must appear in a name given to resolve before an initial absolute query will be made.</td>
</tr>
<tr>
<td rowspan="2">dnsjava.options</td>
<td>option list</td>
<td>-</td>
<td>BINDTTL,tsigfudge=1</td>
</tr>
<tr>
<td colspan="3">Comma separated key-value pairs, see below.</td>
</tr>
<tr>
<td rowspan="2">dnsjava.configprovider.sunjvm.enabled</td>
<td>Boolean</td>
<td>false</td>
<td>true</td>
</tr>
<tr>
<td colspan="3">Set to true to enable the reflection based DNS server lookup, see limitations below.</td>
</tr>
<tr>
<td rowspan="2">dnsjava.udp.ephemeral.start</td>
<td>Integer</td>
<td>49152 (Linux: 32768)</td>
<td>50000</td>
</tr>
<tr>
<td colspan="3">First ephemeral port for UDP-based DNS queries.</td>
</tr>
<tr>
<td rowspan="2">dnsjava.udp.ephemeral.end</td>
<td>Integer</td>
<td>65535 (Linux: 60999)</td>
<td>60000</td>
</tr>
<tr>
<td colspan="3">Last ephemeral port for UDP-based DNS queries.</td>
</tr>
<tr>
<td rowspan="2">dnsjava.udp.ephemeral.use_ephemeral_port</td>
<td>Boolean</td>
<td>false</td>
<td>true</td>
</tr>
<tr>
<td colspan="3">Use an OS-assigned ephemeral port for UDP queries. Enabling this option is insecure! Do NOT use it.</td>
</tr>
</tbody>
</table>

#### dnsjava.options pairs
The dnsjava.options configuration options can also be set programmatically
through the `Options` class. Please refer to the Javadoc for details.

| Key | Type | Default | Explanation |
| --- | ---- | -------| ----------- |
| BINDTTL | Boolean | false | Print TTLs in BIND format |
| multiline | Boolean | false | Print records in multiline format |
| noPrintIN | Boolean | false | Don't print the class of a record if it's IN |
| tsigfudge | Integer | 300 | Sets the default TSIG fudge value (in seconds) |
| sig0validity | Integer | 300 | Sets the default SIG(0) validity period (in seconds) |

### Resolvers
dnsjava comes with several built-in resolvers:
- `SimpleResolver`: a basic resolver that uses UDP by default and falls back
to TCP if required.
- `ExtendedResolver`: a resolver that uses multiple `SimpleResolver`s to send
the queries. Can be configured to query the servers in a round-robin order.
Blacklists a server if it times out.
- `DohResolver`: a very basic DNS over HTTP resolver, e.g. to use
`https://dns.google/query`.

The project [dnssecjava](https://github.com/ibauersachs/dnssecjava) has a
resolver that validates responses with DNSSEC.

### Migrating from version 2.1.x to v3
dnsjava 3 has significant API changes compared to version 2.1.x and is
neither source nor binary compatible. The most important changes are:
- The minimum supported version is Java 8
- Uses [slf4j](http://www.slf4j.org/) for logging and thus needs `slf4j-api`
on the classpath
- The [command line tools](USAGE.md) were moved to the `org.xbill.DNS.tools`
package
- On Windows, [JNA](https://github.com/java-native-access/jna) should be
on the classpath for the search path
- The `Resolver` API for custom resolvers has changed to use
`CompletionStage<Message>` for asynchronous resolving. The built-in
resolvers are now fully non-blocking and do not start a thread per
query anymore.
- Many methods return a `List<T>` instead of an array. Ideally, use a
for-each loop. If this isn't possible, call `size()` instead of
using `length`:
- Cache#findAnyRecords
- Cache#findRecords
- Lookup#getDefaultSearchPath
- Message#getSectionRRsets
- SetResponse#answers
- ResolverConfig
- RRset returns a List<T> instead of an `Iterator`. Ideally, modify your
code to use a for-each loop. If this is not possible, create an iterator
on the returned list:
- RRset#rrs
- RRset#sigs
- Methods using `java.util.Date` are deprecated. Use the new versions with
`java.time.Instant` or `java.time.Duration` instead
- The type hierarchy of `SMIMEARecord` changed, it now inherits from
`TLSARecord` and constants are shared
- `Record`s are no longer marked as `Serializable`. Use the RFC defined
serialization formats:
- `toString()`, `rrToString()` <-> `fromString()`
- `toWire()` <-> `fromWire()`, `newRecord()`
- `Message` and `Header` properly supported `clone()`

### Replacing the standard Java DNS functionality

Java versions from 1.4 to 8 can load DNS service providers at runtime. The
functionality was [removed in JDK 9](https://bugs.openjdk.java.net/browse/JDK-8134577),
a replacement is [requested](https://bugs.openjdk.java.net/browse/JDK-8192780),
but so far has not been implemented.

To load the dnsjava service provider, build dnsjava on a JDK that still
supports the SPI and set the system property:
To load the dnsjava service provider, build dnsjava on JDK 8 and set the system property:

sun.net.spi.nameservice.provider.1=dns,dnsjava

This instructs the JVM to use the dnsjava service provide for DNS at the
highest priority.

### Build

## Testing dnsjava
Run `mvn package` from the toplevel directory to build dnsjava. JDK 8
or higher is required.

[Matt Rutherford](mailto:rutherfo@cs.colorado.edu) contributed a number of unit
tests, which are in the tests subdirectory. The hierarchy under tests
mirrors the org.xbill.DNS classes. To run the unit tests, execute
`mvn test`. The tests require JUnit.
### Testing dnsjava

Some high-level test programs are in `org/xbill/DNS/tests`.
[Matt Rutherford](mailto:rutherfo@cs.colorado.edu) contributed a number of unit
tests, which are in the tests subdirectory. The hierarchy under tests
mirrors the org.xbill.DNS classes. To run the unit tests, execute
`mvn test`.


## Limitations

There's no standard way to determine what the local nameserver or DNS search
path is at runtime from within the JVM. dnsjava attempts several methods
path is at runtime from within the JVM. dnsjava attempts several methods
until one succeeds.

- The properties `dns.server` and `dns.search` (comma delimited lists) are
checked. The servers can either be IP addresses or hostnames (which are
checked. The servers can either be IP addresses or hostnames (which are
resolved using Java's built in DNS support).
- The `sun.net.dns.ResolverConfiguration` class is queried.
- On Unix, `/etc/resolv.conf` is parsed.
- On Windows, `ipconfig`/`winipcfg` is called and its output parsed. This may
fail for non-English versions on Windows.
- On Unix/Solaris, `/etc/resolv.conf` is parsed.
- On Windows, if [JNA](https://github.com/java-native-access/jna) is available
on the classpath, the `GetAdaptersAddresses` API is used.
- On Android, depending on the SDK level, either the properties `net.dns[1234]`
or the `ConnectivityManager` is used (requires initialization).
- The `sun.net.dns.ResolverConfiguration` class is queried if enabled.
- If available and no servers have been found yet,
[JNDI-DNS](https://docs.oracle.com/javase/8/docs/technotes/guides/jndi/jndi-dns.html) is used.
- As a last resort, `localhost` is used as the nameserver, and the search
path is empty.

The underlying platform must use an ASCII encoding of characters. This means
that dnsjava will not work on OS/390, for example.


## Additional documentation

Expand All @@ -103,6 +252,12 @@ at [javadoc.io](http://javadoc.io/doc/dnsjava/dnsjava). See the
dnsjava is placed under the [BSD license](LICENSE). Several files are also under
additional licenses; see the individual files for details.

## Authors

- Brian Wellington (@bwelling), March 12, 2004
- Various contributors, see [Changelog](Changelog)
- Ingo Bauersachs (@ibauersachs), current maintainer

## Final notes
- Thanks to Network Associates, Inc. for sponsoring some of the original
dnsjava work in 1999-2000.
Expand Down

0 comments on commit 02d2816

Please sign in to comment.