rubydns 0.8.5 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/Gemfile +0 -4
- data/README.md +16 -8
- data/Rakefile +6 -6
- data/{test/examples → examples}/dropping-dns.rb +0 -0
- data/lib/rubydns/handler.rb +133 -102
- data/lib/rubydns/message.rb +0 -1
- data/lib/rubydns/resolver.rb +135 -187
- data/lib/rubydns/server.rb +92 -86
- data/lib/rubydns/transaction.rb +24 -48
- data/lib/rubydns/{binary_string.rb → transport.rb} +38 -0
- data/lib/rubydns/version.rb +1 -1
- data/lib/rubydns.rb +15 -8
- data/rubydns.gemspec +5 -2
- data/{test/test_daemon.rb → spec/rubydns/daemon_spec.rb} +36 -48
- data/{test → spec/rubydns}/hosts.txt +0 -0
- data/{test/test_rules.rb → spec/rubydns/message_spec.rb} +26 -44
- data/spec/rubydns/passthrough_spec.rb +78 -0
- data/spec/rubydns/resolver_performance_spec.rb +110 -0
- data/spec/rubydns/resolver_spec.rb +144 -0
- data/spec/rubydns/rules_spec.rb +74 -0
- data/{test/performance → spec/rubydns/server}/benchmark.rb +0 -0
- data/{test/performance → spec/rubydns/server}/bind9/generate-local.rb +0 -0
- data/{test/performance → spec/rubydns/server}/bind9/local.zone +0 -0
- data/{test/performance → spec/rubydns/server}/bind9/named.conf +0 -0
- data/spec/rubydns/server/bind9/named.run +0 -0
- data/{test/performance → spec/rubydns/server}/million.rb +1 -3
- data/spec/rubydns/server/rubydns.stackprof +0 -0
- data/spec/rubydns/server_performance_spec.rb +136 -0
- data/spec/rubydns/slow_server_spec.rb +89 -0
- data/spec/rubydns/socket_spec.rb +77 -0
- data/{test/test_system.rb → spec/rubydns/system_spec.rb} +28 -22
- data/spec/rubydns/transaction_spec.rb +64 -0
- data/{test/test_truncation.rb → spec/rubydns/truncation_spec.rb} +22 -48
- metadata +91 -54
- data/test/examples/fortune-dns.rb +0 -107
- data/test/examples/geoip-dns.rb +0 -76
- data/test/examples/soa-dns.rb +0 -82
- data/test/examples/test-dns-1.rb +0 -77
- data/test/examples/test-dns-2.rb +0 -83
- data/test/examples/wikipedia-dns.rb +0 -112
- data/test/test_message.rb +0 -65
- data/test/test_passthrough.rb +0 -120
- data/test/test_resolver.rb +0 -106
- data/test/test_resolver_performance.rb +0 -123
- data/test/test_server_performance.rb +0 -134
- data/test/test_slow_server.rb +0 -125
data/test/examples/test-dns-2.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
-
#
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'rubydns'
|
24
|
-
require 'process-daemon'
|
25
|
-
|
26
|
-
# To run this command, use the standard daemon syntax as root
|
27
|
-
# ./daemon2.rb start
|
28
|
-
|
29
|
-
# You should be able to see that the server has dropped priviledges
|
30
|
-
# # ps aux | grep daemon2.rb
|
31
|
-
# daemon 16555 0.4 0.0 81392 2024 ?? S 3:35am 0:00.28 ruby ../test/daemon2.rb start
|
32
|
-
|
33
|
-
# Test using the following command
|
34
|
-
# dig @localhost test.mydomain.org
|
35
|
-
# dig +tcp @localhost test.mydomain.org
|
36
|
-
|
37
|
-
# You might need to change the user name "daemon". This can be a user name or a user id.
|
38
|
-
RUN_AS = "daemon"
|
39
|
-
|
40
|
-
INTERFACES = [
|
41
|
-
[:udp, "0.0.0.0", 53],
|
42
|
-
[:tcp, "0.0.0.0", 53]
|
43
|
-
]
|
44
|
-
|
45
|
-
# We need to be root in order to bind to privileged port
|
46
|
-
if RExec.current_user != "root"
|
47
|
-
$stderr.puts "Sorry, this command needs to be run as root!"
|
48
|
-
exit 1
|
49
|
-
end
|
50
|
-
|
51
|
-
# The Daemon itself
|
52
|
-
class Server < Process::Daemon
|
53
|
-
Name = Resolv::DNS::Name
|
54
|
-
IN = Resolv::DNS::Resource::IN
|
55
|
-
|
56
|
-
# Use upstream DNS for name resolution.
|
57
|
-
UPSTREAM = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
|
58
|
-
|
59
|
-
def startup
|
60
|
-
# Don't buffer output (for debug purposes)
|
61
|
-
$stderr.sync = true
|
62
|
-
|
63
|
-
# Start the RubyDNS server
|
64
|
-
RubyDNS::run_server(:listen => INTERFACES) do
|
65
|
-
on(:start) do
|
66
|
-
RExec.change_user(RUN_AS)
|
67
|
-
end
|
68
|
-
|
69
|
-
match("test.mydomain.org", IN::A) do |transaction|
|
70
|
-
transaction.respond!("10.0.0.80")
|
71
|
-
end
|
72
|
-
|
73
|
-
# Default DNS handler
|
74
|
-
otherwise do |transaction|
|
75
|
-
logger.info "Passthrough: #{transaction}"
|
76
|
-
transaction.passthrough!(UPSTREAM)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
# RExec daemon runner
|
83
|
-
Server.daemonize
|
@@ -1,112 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
# Copyright, 2009, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
5
|
-
#
|
6
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
-
# of this software and associated documentation files (the "Software"), to deal
|
8
|
-
# in the Software without restriction, including without limitation the rights
|
9
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
-
# copies of the Software, and to permit persons to whom the Software is
|
11
|
-
# furnished to do so, subject to the following conditions:
|
12
|
-
#
|
13
|
-
# The above copyright notice and this permission notice shall be included in
|
14
|
-
# all copies or substantial portions of the Software.
|
15
|
-
#
|
16
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
-
# THE SOFTWARE.
|
23
|
-
|
24
|
-
require 'rubydns'
|
25
|
-
require 'rubydns/extensions/string'
|
26
|
-
|
27
|
-
require 'process/daemon'
|
28
|
-
|
29
|
-
require 'em-http'
|
30
|
-
require 'cgi'
|
31
|
-
require 'nokogiri'
|
32
|
-
require 'json'
|
33
|
-
|
34
|
-
require 'digest/md5'
|
35
|
-
|
36
|
-
# You might need to change the user name "daemon". This can be a user name or a user id.
|
37
|
-
RUN_AS = "daemon"
|
38
|
-
|
39
|
-
if RExec.current_user != "root"
|
40
|
-
$stderr.puts "Sorry, this command needs to be run as root!"
|
41
|
-
exit 1
|
42
|
-
end
|
43
|
-
|
44
|
-
module Wikipedia
|
45
|
-
def self.summary_url(title)
|
46
|
-
"http://en.wikipedia.org/w/api.php?action=parse&page=#{CGI.escape title}&prop=text§ion=0&format=json"
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.extract_summary(json_text)
|
50
|
-
document = JSON::parse(json_text)
|
51
|
-
return Nokogiri::HTML(document["parse"]["text"]["*"]).css('p')[0].text
|
52
|
-
rescue
|
53
|
-
return "Invalid Article."
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# To use, start the daemon and try:
|
58
|
-
# dig @localhost fortune CNAME
|
59
|
-
class WikipediaDNS < Process::Daemon
|
60
|
-
Name = Resolv::DNS::Name
|
61
|
-
IN = Resolv::DNS::Resource::IN
|
62
|
-
|
63
|
-
def startup
|
64
|
-
# Don't buffer output (for debug purposes)
|
65
|
-
$stderr.sync = true
|
66
|
-
|
67
|
-
cache = {}
|
68
|
-
stats = {:requested => 0}
|
69
|
-
|
70
|
-
# Start the RubyDNS server
|
71
|
-
RubyDNS::run_server do
|
72
|
-
on(:start) do
|
73
|
-
RExec.change_user(RUN_AS)
|
74
|
-
if ARGV.include?("--debug")
|
75
|
-
@logger.level = Logger::DEBUG
|
76
|
-
else
|
77
|
-
@logger.level = Logger::WARN
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
match(/stats\.wikipedia/, IN::TXT) do |transaction|
|
82
|
-
transaction.respond!(*stats.inspect.chunked)
|
83
|
-
end
|
84
|
-
|
85
|
-
match(/(.+)\.wikipedia/, IN::TXT) do |transaction, match_data|
|
86
|
-
title = match_data[1]
|
87
|
-
stats[:requested] += 1
|
88
|
-
|
89
|
-
transaction.defer!
|
90
|
-
|
91
|
-
http = EventMachine::HttpRequest.new(Wikipedia.summary_url(title)).get
|
92
|
-
|
93
|
-
http.callback do
|
94
|
-
summary = Wikipedia.extract_summary(http.response)
|
95
|
-
transaction.respond!(*summary.chunked)
|
96
|
-
end
|
97
|
-
|
98
|
-
http.errback do
|
99
|
-
transaction.fail!(:ServFail)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# Default DNS handler
|
104
|
-
otherwise do |transaction|
|
105
|
-
transaction.fail!(:NXDomain)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# RExec daemon runner
|
112
|
-
WikipediaDNS.daemonize
|
data/test/test_message.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
-
#
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'minitest/autorun'
|
24
|
-
|
25
|
-
require 'rubydns'
|
26
|
-
|
27
|
-
class MessageTest < MiniTest::Test
|
28
|
-
def setup
|
29
|
-
end
|
30
|
-
|
31
|
-
def teardown
|
32
|
-
end
|
33
|
-
|
34
|
-
def hex2bin(hexstring)
|
35
|
-
ret = "\x00" * (hexstring.length / 2)
|
36
|
-
ret.force_encoding("BINARY")
|
37
|
-
offset = 0
|
38
|
-
while offset < hexstring.length
|
39
|
-
hex_byte = hexstring[offset..(offset+1)]
|
40
|
-
ret.setbyte(offset/2, hex_byte.to_i(16))
|
41
|
-
offset += 2
|
42
|
-
end
|
43
|
-
ret
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_good_decode
|
47
|
-
data = hex2bin("1d008180000100080000000103777777057961686f6f03636f6d0000010001c00c000500010000012c000f0666642d667033037767310162c010c02b000500010000012c00090664732d667033c032c046000500010000003c00150e64732d616e792d6670332d6c666203776131c036c05b000500010000012c00120f64732d616e792d6670332d7265616cc06ac07c000100010000003c0004628afc1ec07c000100010000003c0004628bb495c07c000100010000003c0004628bb718c07c000100010000003c0004628afd6d0000291000000000000000")
|
48
|
-
|
49
|
-
decoded = RubyDNS.decode_message(data)
|
50
|
-
assert_equal(RubyDNS::Message, decoded.class)
|
51
|
-
assert_equal(0x1d00, decoded.id)
|
52
|
-
assert_equal(1, decoded.question.count)
|
53
|
-
assert_equal(8, decoded.answer.count)
|
54
|
-
assert_equal(0, decoded.authority.count)
|
55
|
-
assert_equal(1, decoded.additional.count)
|
56
|
-
end
|
57
|
-
|
58
|
-
def test_bad_AAAA_length
|
59
|
-
data = hex2bin("ea9e8180000100010000000108626169636169636e03636f6d00001c0001c00c001c00010000011e000432177b770000291000000000000000")
|
60
|
-
|
61
|
-
assert_raises Resolv::DNS::DecodeError do
|
62
|
-
RubyDNS.decode_message(data)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
data/test/test_passthrough.rb
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
-
#
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'minitest/autorun'
|
24
|
-
|
25
|
-
require 'rubydns'
|
26
|
-
|
27
|
-
require 'process/daemon'
|
28
|
-
|
29
|
-
class PassthroughServer < Process::Daemon
|
30
|
-
SERVER_PORTS = [[:udp, '127.0.0.1', 5340], [:tcp, '127.0.0.1', 5340]]
|
31
|
-
|
32
|
-
def working_directory
|
33
|
-
File.expand_path("../tmp", __FILE__)
|
34
|
-
end
|
35
|
-
|
36
|
-
Name = Resolv::DNS::Name
|
37
|
-
IN = Resolv::DNS::Resource::IN
|
38
|
-
|
39
|
-
def startup
|
40
|
-
resolver = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
|
41
|
-
|
42
|
-
# Start the RubyDNS server
|
43
|
-
RubyDNS::run_server(:listen => SERVER_PORTS) do
|
44
|
-
match(/.*\.com/, IN::A) do |transaction|
|
45
|
-
transaction.passthrough!(resolver)
|
46
|
-
end
|
47
|
-
|
48
|
-
match(/a-(.*\.org)/) do |transaction, match_data|
|
49
|
-
transaction.passthrough!(resolver, :name => match_data[1])
|
50
|
-
end
|
51
|
-
|
52
|
-
# Default DNS handler
|
53
|
-
otherwise do |transaction|
|
54
|
-
transaction.fail!(:NXDomain)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
class PassthroughTest < MiniTest::Test
|
61
|
-
def setup
|
62
|
-
PassthroughServer.controller output: File.open("/dev/null", "w")
|
63
|
-
|
64
|
-
PassthroughServer.start
|
65
|
-
end
|
66
|
-
|
67
|
-
def teardown
|
68
|
-
PassthroughServer.stop
|
69
|
-
end
|
70
|
-
|
71
|
-
def test_basic_dns
|
72
|
-
answer = nil, response = nil
|
73
|
-
|
74
|
-
assert_equal :running, PassthroughServer.status
|
75
|
-
|
76
|
-
EventMachine.run do
|
77
|
-
resolver = RubyDNS::Resolver.new(
|
78
|
-
PassthroughServer::SERVER_PORTS,
|
79
|
-
# Enable this to get more debug output from the resolver:
|
80
|
-
# :logger => Logger.new($stderr)
|
81
|
-
)
|
82
|
-
|
83
|
-
resolver.query("google.com") do |response|
|
84
|
-
refute_kind_of RubyDNS::ResolutionFailure, response
|
85
|
-
|
86
|
-
assert_equal 1, response.ra
|
87
|
-
|
88
|
-
answer = response.answer.first
|
89
|
-
|
90
|
-
EventMachine.stop
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
# Check whether we got some useful records in the answer:
|
95
|
-
refute_nil answer
|
96
|
-
assert answer.count > 0
|
97
|
-
assert answer.any? {|record| record.kind_of? Resolv::DNS::Resource::IN::A}
|
98
|
-
end
|
99
|
-
|
100
|
-
def test_basic_dns_prefix
|
101
|
-
answer = nil
|
102
|
-
|
103
|
-
assert_equal :running, PassthroughServer.status
|
104
|
-
|
105
|
-
EventMachine.run do
|
106
|
-
resolver = RubyDNS::Resolver.new(PassthroughServer::SERVER_PORTS)
|
107
|
-
|
108
|
-
resolver.query("a-slashdot.org") do |response|
|
109
|
-
refute_kind_of RubyDNS::ResolutionFailure, response
|
110
|
-
|
111
|
-
answer = response.answer.first
|
112
|
-
|
113
|
-
EventMachine.stop
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
assert answer != nil
|
118
|
-
assert answer.count > 0
|
119
|
-
end
|
120
|
-
end
|
data/test/test_resolver.rb
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
-
#
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'minitest/autorun'
|
24
|
-
|
25
|
-
require 'rubydns'
|
26
|
-
|
27
|
-
class ResolverTest < MiniTest::Test
|
28
|
-
def test_basic_resolver
|
29
|
-
resolver = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
|
30
|
-
|
31
|
-
EventMachine::run do
|
32
|
-
resolver.query('google.com') do |response|
|
33
|
-
assert_equal RubyDNS::Message, response.class
|
34
|
-
EventMachine::stop
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
EventMachine::run do
|
39
|
-
resolver.query('foobar.oriontransfer.org') do |response|
|
40
|
-
assert_equal Resolv::DNS::RCode::NXDomain, response.rcode
|
41
|
-
EventMachine::stop
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_broken_resolver
|
47
|
-
resolver = RubyDNS::Resolver.new([])
|
48
|
-
|
49
|
-
EventMachine::run do
|
50
|
-
resolver.query('google.com') do |response|
|
51
|
-
assert_equal RubyDNS::ResolutionFailure, response.class
|
52
|
-
|
53
|
-
EventMachine::stop
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
class MockRequest
|
59
|
-
attr :response
|
60
|
-
|
61
|
-
def process_response!(response)
|
62
|
-
@response = response
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_dirty_packets_udp
|
67
|
-
mock_request = MockRequest.new
|
68
|
-
|
69
|
-
handler_class = Class.new{ include RubyDNS::Resolver::Request::UDPRequestHandler }
|
70
|
-
handler = handler_class.new(mock_request, nil, nil)
|
71
|
-
|
72
|
-
handler.receive_data("This is not a real message!")
|
73
|
-
|
74
|
-
assert_equal Resolv::DNS::DecodeError, mock_request.response.class
|
75
|
-
end
|
76
|
-
|
77
|
-
def test_dirty_packets_tcp
|
78
|
-
mock_request = MockRequest.new
|
79
|
-
|
80
|
-
handler_class = Class.new{ include RubyDNS::Resolver::Request::TCPRequestHandler }
|
81
|
-
handler = handler_class.new(mock_request)
|
82
|
-
|
83
|
-
data = "This is not a real message!"
|
84
|
-
handler.receive_data([data.length].pack('n') + data)
|
85
|
-
|
86
|
-
assert_equal Resolv::DNS::DecodeError, mock_request.response.class
|
87
|
-
end
|
88
|
-
|
89
|
-
def test_addresses_for
|
90
|
-
resolver = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
|
91
|
-
resolved_addresses = nil
|
92
|
-
|
93
|
-
EventMachine::run do
|
94
|
-
resolver.addresses_for("www.google.com.") do |addresses|
|
95
|
-
resolved_addresses = addresses
|
96
|
-
|
97
|
-
EventMachine::stop
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
assert resolved_addresses.count > 0
|
102
|
-
|
103
|
-
address = resolved_addresses[0]
|
104
|
-
assert address.kind_of?(Resolv::IPv4) || address.kind_of?(Resolv::IPv6)
|
105
|
-
end
|
106
|
-
end
|
@@ -1,123 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
-
#
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
# of this software and associated documentation files (the "Software"), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in
|
13
|
-
# all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
# THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'minitest/autorun'
|
24
|
-
|
25
|
-
require 'rubydns'
|
26
|
-
require 'rubydns/system'
|
27
|
-
|
28
|
-
require 'benchmark'
|
29
|
-
|
30
|
-
class ResolverPerformanceTest < MiniTest::Test
|
31
|
-
# The larger this number, the better RubyDNS::Resolver will look as it is highly asynchronous.
|
32
|
-
DOMAINS = %W{
|
33
|
-
Facebook.com
|
34
|
-
Twitter.com
|
35
|
-
Google.com
|
36
|
-
Youtube.com
|
37
|
-
Wordpress.org
|
38
|
-
Adobe.com
|
39
|
-
Blogspot.com
|
40
|
-
Wikipedia.org
|
41
|
-
Linkedin.com
|
42
|
-
Wordpress.com
|
43
|
-
Yahoo.com
|
44
|
-
Amazon.com
|
45
|
-
Flickr.com
|
46
|
-
Pinterest.com
|
47
|
-
Tumblr.com
|
48
|
-
W3.org
|
49
|
-
Apple.com
|
50
|
-
Myspace.com
|
51
|
-
Vimeo.com
|
52
|
-
Microsoft.com
|
53
|
-
Youtu.be
|
54
|
-
Qq.com
|
55
|
-
Digg.com
|
56
|
-
Baidu.com
|
57
|
-
Stumbleupon.com
|
58
|
-
Addthis.com
|
59
|
-
Statcounter.com
|
60
|
-
Feedburner.com
|
61
|
-
TradeMe.co.nz
|
62
|
-
Delicious.com
|
63
|
-
Nytimes.com
|
64
|
-
Reddit.com
|
65
|
-
Weebly.com
|
66
|
-
Bbc.co.uk
|
67
|
-
Blogger.com
|
68
|
-
Msn.com
|
69
|
-
Macromedia.com
|
70
|
-
Goo.gl
|
71
|
-
Instagram.com
|
72
|
-
Gov.uk
|
73
|
-
Icio.us
|
74
|
-
Yandex.ru
|
75
|
-
Cnn.com
|
76
|
-
Webs.com
|
77
|
-
Google.de
|
78
|
-
T.co
|
79
|
-
Livejournal.com
|
80
|
-
Imdb.com
|
81
|
-
Mail.ru
|
82
|
-
Jimdo.com
|
83
|
-
}
|
84
|
-
|
85
|
-
def test_resolvers
|
86
|
-
rubydns_resolved = {}
|
87
|
-
resolv_resolved = {}
|
88
|
-
|
89
|
-
puts nil, "Comparing resolvers..."
|
90
|
-
Benchmark.bm(20) do |x|
|
91
|
-
x.report("RubyDNS::Resolver") do
|
92
|
-
resolver = RubyDNS::Resolver.new([[:udp, "8.8.8.8", 53], [:tcp, "8.8.8.8", 53]])
|
93
|
-
|
94
|
-
# Number of requests remaining since this is an asynchronous event loop:
|
95
|
-
pending = DOMAINS.size
|
96
|
-
|
97
|
-
EventMachine::run do
|
98
|
-
DOMAINS.each do |domain|
|
99
|
-
resolver.addresses_for(domain) do |addresses|
|
100
|
-
rubydns_resolved[domain] = addresses
|
101
|
-
|
102
|
-
EventMachine::stop if (pending -= 1) == 0
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
x.report("Resolv::DNS") do
|
109
|
-
resolver = Resolv::DNS.new(:nameserver => "8.8.8.8")
|
110
|
-
|
111
|
-
DOMAINS.each do |domain|
|
112
|
-
resolv_resolved[domain] = resolver.getaddresses(domain)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
DOMAINS.first(3).each do |domain|
|
118
|
-
# We don't really care if the responses aren't identical - they should be most of the time but due to the way DNS works this isn't always the case:
|
119
|
-
refute_empty resolv_resolved[domain]
|
120
|
-
refute_empty rubydns_resolved[domain]
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|