Skip to content

Commit 789526d

Browse files
committed
Update documentation.
1 parent 9599751 commit 789526d

File tree

6 files changed

+141
-125
lines changed

6 files changed

+141
-125
lines changed

async-dns.gemspec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Gem::Specification.new do |spec|
1616
spec.homepage = "https://github.com/socketry/async-dns"
1717

1818
spec.metadata = {
19+
"documentation_uri" => "https://socketry.github.io/async-dns/",
20+
"funding_uri" => "https://github.com/sponsors/ioquatix/",
1921
"source_code_uri" => "https://github.com/socketry/async-dns.git",
2022
}
2123

guides/getting-started/readme.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Getting Started
2+
3+
This guide explains how to get started with the `async-dns` gem.
4+
5+
## Installation
6+
7+
Add the gem to your project:
8+
9+
~~~ bash
10+
$ bundle add async-dns
11+
~~~
12+
13+
## Usage
14+
15+
### Resolver
16+
17+
Here is a simple example showing how to use the resolver:
18+
19+
``` ruby
20+
Async do
21+
resolver = Async::DNS::System.resolver
22+
23+
addresses = resolver.addresses_for("www.google.com.")
24+
25+
puts addresses.inspect
26+
end
27+
# [#<Resolv::IPv4 202.124.127.240>, #<Resolv::IPv4 202.124.127.216>, #<Resolv::IPv4 202.124.127.223>, #<Resolv::IPv4 202.124.127.227>, #<Resolv::IPv4 202.124.127.234>, #<Resolv::IPv4 202.124.127.230>, #<Resolv::IPv4 202.124.127.208>, #<Resolv::IPv4 202.124.127.249>, #<Resolv::IPv4 202.124.127.219>, #<Resolv::IPv4 202.124.127.218>, #<Resolv::IPv4 202.124.127.212>, #<Resolv::IPv4 202.124.127.241>, #<Resolv::IPv4 202.124.127.238>, #<Resolv::IPv4 202.124.127.245>, #<Resolv::IPv4 202.124.127.251>, #<Resolv::IPv4 202.124.127.229>]
28+
```
29+
30+
### Server
31+
32+
Here is a simple example showing how to use the server:
33+
34+
``` ruby
35+
require 'async/dns'
36+
37+
class TestServer < Async::DNS::Server
38+
def resolver
39+
@resolver ||= Async::DNS::Resolver.new(
40+
Async::DNS::Endpoint.for('1.1.1.1')
41+
)
42+
end
43+
44+
def process(name, resource_class, transaction)
45+
transaction.passthrough!(self.resolver)
46+
end
47+
end
48+
49+
endpoint = Async::DNS::Endpoint.for('localhost', port: 5300)
50+
server = TestServer.new(endpoint)
51+
server.run
52+
```
53+
54+
Then to test you could use `dig` like so:
55+
56+
dig @localhost -p 5300 google.com
57+
58+
## FAQ
59+
60+
### File Handle Limitations
61+
62+
I get the error `Errno::EMFILE: Too many open files - socket(2) - udp` when trying to run a server. What should I do?
63+
64+
On some platforms (e.g. Mac OS X) the number of file descriptors is relatively low by default and should be increased by calling `ulimit -n 10000` before running tests or even before starting a server which expects a large number of concurrent incoming connections.
65+
66+
### Server
67+
68+
The performance is on the same magnitude as `bind9`. Some basic benchmarks resolving 1000 names concurrently, repeated 5 times, using `Async::DNS::Resolver` gives the following:
69+
70+
```
71+
user system total real
72+
Async::DNS::Server 4.280000 0.450000 4.730000 ( 4.854862)
73+
Bind9 4.970000 0.520000 5.490000 ( 5.541213)
74+
```
75+
76+
These benchmarks are included in the unit tests. To test bind9 performance, it must be installed and `which named` must return the executable.
77+
78+
## Performance
79+
80+
We welcome additional benchmarks and feedback regarding Async::DNS performance. To check the current performance results, consult the [travis build job output](https://travis-ci.org/socketry/async-dns).
81+
82+
### Resolver
83+
84+
The `Async::DNS::Resolver` is highly concurrent and can resolve individual names as fast as the built in `Resolv::DNS` resolver. Because the resolver is asynchronous, when dealing with multiple names, it can work more efficiently:
85+
86+
```
87+
user system total real
88+
Async::DNS::Resolver 0.020000 0.010000 0.030000 ( 0.030507)
89+
Resolv::DNS 0.070000 0.010000 0.080000 ( 1.465975)
90+
```
91+
92+
These benchmarks are included in the unit tests.
93+
94+
### Server
95+
96+
The performance is on the same magnitude as `bind9`. Some basic benchmarks resolving 1000 names concurrently, repeated 5 times, using `Async::DNS::Resolver` gives the following:
97+
98+
```
99+
user system total real
100+
Async::DNS::Server 4.280000 0.450000 4.730000 ( 4.854862)
101+
Bind9 4.970000 0.520000 5.490000 ( 5.541213)
102+
```
103+
104+
These benchmarks are included in the unit tests. To test bind9 performance, it must be installed and `which named` must return the executable.
105+
106+
### DNSSEC support
107+
108+
DNSSEC is currently not supported and is [unlikely to be supported in the future](http://sockpuppet.org/blog/2015/01/15/against-dnssec/). Feel free to submit a PR.

guides/links.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
getting-started:
2+
order: 0

lib/async/dns/endpoint.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2024, by Samuel Williams.
5+
6+
7+
8+
module Async
9+
module DNS
10+
module Endpoint
11+
# Get a list of standard nameserver connections which can be used for querying any standard servers that the system has been configured with.
12+
def self.for(nameservers, port: 53, **options)
13+
connections = []
14+
15+
Array(nameservers).each do |host|
16+
connections << IO::Endpoint.udp(host, port, **options)
17+
connections << IO::Endpoint.tcp(host, port, **options)
18+
end
19+
20+
return IO::Endpoint.composite(*connections)
21+
end
22+
end
23+
end
24+
end

lib/async/dns/system.rb

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
# Released under the MIT License.
44
# Copyright, 2015-2024, by Samuel Williams.
55

6+
require_relative 'endpoint'
7+
68
begin
79
require 'win32/resolv'
810
rescue LoadError
@@ -147,18 +149,6 @@ def self.parse_resolv_configuration(path)
147149
}
148150
end
149151

150-
# Get a list of standard nameserver connections which can be used for querying any standard servers that the system has been configured with.
151-
def self.endpoint_for(nameservers, **options)
152-
connections = []
153-
154-
nameservers.each do |host|
155-
connections << IO::Endpoint.udp(host, 53, **options)
156-
connections << IO::Endpoint.tcp(host, 53, **options)
157-
end
158-
159-
return IO::Endpoint.composite(connections)
160-
end
161-
162152
# Get a list of standard nameserver connections which can be used for querying any standard servers that the system has been configured with. There is no equivalent facility to use the `hosts` file at present.
163153
def self.resolver(**options)
164154
nameservers = []
@@ -180,7 +170,7 @@ def self.resolver(**options)
180170
end
181171

182172
timeout = options.delete(:timeout) || DEFAULT_TIMEOUT
183-
endpoint = self.endpoint_for(nameservers, timeout: timeout)
173+
endpoint = Endpoint.for(nameservers, timeout: timeout)
184174

185175
if block_given?
186176
yield endpoint, **options

readme.md

Lines changed: 2 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -4,121 +4,11 @@ Async::DNS is a high-performance DNS client resolver and server which can be eas
44

55
[![Development Status](https://github.com/socketry/async-dns/workflows/Test/badge.svg)](https://github.com/socketry/async-dns/actions?workflow=Test)
66

7-
## Installation
8-
9-
Add this line to your application's Gemfile:
10-
11-
gem 'async-dns'
12-
13-
And then execute:
14-
15-
$ bundle
16-
17-
Or install it yourself as:
18-
19-
$ gem install async-dns
20-
217
## Usage
228

23-
### Resolver
24-
25-
Here is a simple example showing how to use the resolver:
26-
27-
``` ruby
28-
Async::Reactor.run do
29-
resolver = Async::DNS::System.resolver
30-
31-
addresses = resolver.addresses_for("www.google.com.")
32-
33-
puts addresses.inspect
34-
end
35-
# [#<Resolv::IPv4 202.124.127.240>, #<Resolv::IPv4 202.124.127.216>, #<Resolv::IPv4 202.124.127.223>, #<Resolv::IPv4 202.124.127.227>, #<Resolv::IPv4 202.124.127.234>, #<Resolv::IPv4 202.124.127.230>, #<Resolv::IPv4 202.124.127.208>, #<Resolv::IPv4 202.124.127.249>, #<Resolv::IPv4 202.124.127.219>, #<Resolv::IPv4 202.124.127.218>, #<Resolv::IPv4 202.124.127.212>, #<Resolv::IPv4 202.124.127.241>, #<Resolv::IPv4 202.124.127.238>, #<Resolv::IPv4 202.124.127.245>, #<Resolv::IPv4 202.124.127.251>, #<Resolv::IPv4 202.124.127.229>]
36-
```
37-
38-
You can also specify custom DNS servers:
39-
40-
``` ruby
41-
resolver = Async::DNS::Resolver.new(Async::DNS::System.standard_connections(['8.8.8.8']))
42-
43-
# or
44-
45-
resolver = Async::DNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
46-
```
47-
48-
### Server
49-
50-
Here is a simple example showing how to use the server:
51-
52-
``` ruby
53-
require 'async/dns'
54-
55-
class TestServer < Async::DNS::Server
56-
def process(name, resource_class, transaction)
57-
@resolver ||= Async::DNS::Resolver.new([[:udp, '8.8.8.8', 53], [:tcp, '8.8.8.8', 53]])
58-
59-
transaction.passthrough!(@resolver)
60-
end
61-
end
62-
63-
server = TestServer.new([[:udp, '127.0.0.1', 2346]])
64-
server.run
65-
```
66-
67-
Then to test you could use `dig` like so:
68-
69-
dig @localhost -p 2346 google.com
70-
71-
## FAQ
72-
73-
### File Handle Limitations
74-
75-
I get the error `Errno::EMFILE: Too many open files - socket(2) - udp` when trying to run a server. What should I do?
76-
77-
On some platforms (e.g. Mac OS X) the number of file descriptors is relatively low by default and should be increased by calling `ulimit -n 10000` before running tests or even before starting a server which expects a large number of concurrent incoming connections.
78-
79-
### Server
80-
81-
The performance is on the same magnitude as `bind9`. Some basic benchmarks resolving 1000 names concurrently, repeated 5 times, using `Async::DNS::Resolver` gives the following:
82-
83-
```
84-
user system total real
85-
Async::DNS::Server 4.280000 0.450000 4.730000 ( 4.854862)
86-
Bind9 4.970000 0.520000 5.490000 ( 5.541213)
87-
```
88-
89-
These benchmarks are included in the unit tests. To test bind9 performance, it must be installed and `which named` must return the executable.
90-
91-
## Performance
92-
93-
We welcome additional benchmarks and feedback regarding Async::DNS performance. To check the current performance results, consult the [travis build job output](https://travis-ci.org/socketry/async-dns).
94-
95-
### Resolver
96-
97-
The `Async::DNS::Resolver` is highly concurrent and can resolve individual names as fast as the built in `Resolv::DNS` resolver. Because the resolver is asynchronous, when dealing with multiple names, it can work more efficiently:
98-
99-
```
100-
user system total real
101-
Async::DNS::Resolver 0.020000 0.010000 0.030000 ( 0.030507)
102-
Resolv::DNS 0.070000 0.010000 0.080000 ( 1.465975)
103-
```
104-
105-
These benchmarks are included in the unit tests.
106-
107-
### Server
108-
109-
The performance is on the same magnitude as `bind9`. Some basic benchmarks resolving 1000 names concurrently, repeated 5 times, using `Async::DNS::Resolver` gives the following:
110-
111-
```
112-
user system total real
113-
Async::DNS::Server 4.280000 0.450000 4.730000 ( 4.854862)
114-
Bind9 4.970000 0.520000 5.490000 ( 5.541213)
115-
```
116-
117-
These benchmarks are included in the unit tests. To test bind9 performance, it must be installed and `which named` must return the executable.
118-
119-
### DNSSEC support
9+
Please see the [project documentation](https://socketry.github.io/async-dns/) for more details.
12010

121-
DNSSEC is currently not supported and is [unlikely to be supported in the future](http://sockpuppet.org/blog/2015/01/15/against-dnssec/). Feel free to submit a PR.
11+
- [Getting Started](https://socketry.github.io/async-dns/guides/getting-started/index) - This guide explains how to get started with the `async-dns` gem.
12212

12313
## Contributing
12414

0 commit comments

Comments
 (0)