-
Notifications
You must be signed in to change notification settings - Fork 125
Getting Started ‐ Library
- README.md for more info on installation and the intent of this tool
- Getting Started - Library
- Getting Started - CLI
-
./zdns --help
flag for more info on all available flags and options for the CLI
If after consulting this documentation you still have questions, please feel free to open an issue on the GitHub repo so we can update this community resource!
The ZDNS library is designed to give an interface to ZDNS from another Golang program. All options available in the CLI are available in the library. This approach gives the user the flexibility to use ZDNS in their own programs, full control of the threading behavior, and the ability to customize ZDNS to their needs.
Here, we'll be looking at the simple lookup example in examples/simple_lookup/simple.go
At a high-level, using the library follows the following steps:
- Create a
ResolverConfig
object - Set any desired options on the
ResolverConfig
object - Create a/multiple new
Resolver
object(s) with theResolverConfig
object - Use the
Resolver
object to perform DNS lookups
The ResolverConfig
holds all configuration info for a Resolver
object. The Resolver
object performs the actual DNS lookups.
The Resolver
object can perform two types of lookups: External and Iterative.
- External lookups utilize a recursive resolver (
1.1.1.1
or8.8.8.8
, for example) to perform the lookup.- If you provide an empty string for the
dstServer
parameter, the library will use external lookups specified in theResolverConfig
. By default, these are set to the OS's default DNS resolver(s). - You can provide an
IP:port
pair to override this behavior at the function-call level todstServer
.
- If you provide an empty string for the
- Iterative lookups perform the lookup starting from the root servers and following the DNS resolution process to the end. You do not need to provide a
dstServer
parameter for iterative lookups as all recursion happens internally.- Iterative lookups are slower than external lookups, but ZDNS does implement an LRU caching mechanism to cache the most common domain name -> IPs to speed up this process.
- Iterative lookups are useful for when you want to see the entire resolution process, or if you want to see the entire chain of responses from the root servers to the final authoritative server.
Please see the examples/simple_lookup/simple.go
for an example.
To improve performance, and a primary feature of ZDNS over other DNS tools like dig
, is it's use of a cache.
The cache is an LRU cache that stores the most common domain name -> IP mappings to speed up iterative lookups.
This cache is intended to be shared across multiple Resolver
objects to reduce overhead.
A Resolver object is not thread-safe, so if you want to perform multiple lookups concurrently, you should create a new Resolver object for each goroutine.
As the cache and the blacklist are pointers (to enable sharing of the struct across multiple resolvers, they are thread-safe), you should not change the ResolverConfig
after creating a Resolver object. If you need to change the configuration post-Resolver
creation, create a new ResolverConfig
object with the new configuration.
A pattern we follow in the CLI is to create a worker pool of goroutines, each with their own Resolver object, and a shared Blacklist and Cache between them. An input channel is used to pass the domain names to the worker pool, and an output channel is used to pass the results back to the main goroutine.
An example of a simple multi-threaded use-case with a worker pool and shared cache can be found in examples/multi_threaded_lookup/multi_threaded.go
here.
For a more complex example, see the Run
function in src/cli/worker_manager.go