dnsruby 1.58.0 → 1.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +11 -0
- data/RELEASE_NOTES.md +15 -0
- data/Rakefile +2 -1
- data/demo/axfr.rb +84 -85
- data/demo/check_soa.rb +115 -94
- data/demo/check_zone.rb +69 -64
- data/demo/digdlv.rb +22 -24
- data/demo/digroot.rb +23 -19
- data/demo/example_recurse.rb +20 -6
- data/demo/mresolv.rb +26 -14
- data/demo/mx.rb +21 -11
- data/demo/rubydig.rb +34 -25
- data/demo/trace_dns.rb +22 -16
- data/lib/dnsruby/cache.rb +8 -0
- data/lib/dnsruby/config.rb +1 -1
- data/lib/dnsruby/dnssec.rb +6 -2
- data/lib/dnsruby/message/decoder.rb +1 -0
- data/lib/dnsruby/message/question.rb +1 -1
- data/lib/dnsruby/packet_sender.rb +4 -0
- data/lib/dnsruby/recursor.rb +9 -1
- data/lib/dnsruby/resource/OPT.rb +2 -2
- data/lib/dnsruby/resource/RR.rb +4 -4
- data/lib/dnsruby/select_thread.rb +2 -2
- data/lib/dnsruby/single_verifier.rb +24 -4
- data/lib/dnsruby/update.rb +1 -1
- data/lib/dnsruby/validator_thread.rb +2 -1
- data/lib/dnsruby/version.rb +1 -1
- data/test/tc_axfr.rb +1 -1
- data/test/tc_cache.rb +45 -9
- data/test/tc_dns.rb +64 -50
- data/test/tc_message.rb +17 -1
- data/test/tc_res_config.rb +3 -2
- data/test/tc_resolv.rb +1 -1
- data/test/tc_single_resolver.rb +148 -132
- data/test/ts_online.rb +7 -0
- metadata +3 -2
data/demo/check_zone.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
1
3
|
# --
|
2
4
|
# Copyright 2007 Nominet UK
|
3
5
|
#
|
@@ -28,6 +30,7 @@
|
|
28
30
|
#
|
29
31
|
# * Checks that all A records have corresponding PTR records.
|
30
32
|
#
|
33
|
+
|
31
34
|
# * Checks that hosts listed in NS, MX, and CNAME records have
|
32
35
|
# A records.
|
33
36
|
#
|
@@ -42,132 +45,134 @@
|
|
42
45
|
#
|
43
46
|
|
44
47
|
|
48
|
+
def fatal_error(message)
|
49
|
+
puts message
|
50
|
+
exit(-1)
|
51
|
+
end
|
52
|
+
|
53
|
+
unless (1..2).include?(ARGV.length)
|
54
|
+
fatal_error("Usage: #{$0} domain [ class ]")
|
55
|
+
end
|
56
|
+
|
57
|
+
|
45
58
|
require 'dnsruby'
|
46
59
|
require 'getoptLong'
|
47
60
|
|
61
|
+
|
48
62
|
def check_domain(args)
|
49
63
|
domain = args[0]
|
50
|
-
klass =
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
res.retry_times=(2)
|
60
|
-
nspack = nil
|
61
|
-
begin
|
62
|
-
nspack = res.query(domain, "NS", klass)
|
64
|
+
klass = args[1] || 'IN'
|
65
|
+
puts "----------------------------------------------------------------------"
|
66
|
+
puts "#{domain} (class #{klass}\n"
|
67
|
+
puts "----------------------------------------------------------------------"
|
68
|
+
|
69
|
+
resolver = Dnsruby::Resolver.new
|
70
|
+
resolver.retry_times = 2
|
71
|
+
nspack = begin
|
72
|
+
resolver.query(domain, 'NS', klass)
|
63
73
|
rescue Exception => e
|
64
74
|
print "Couldn't find nameservers for #{domain}: #{e}\n"
|
65
75
|
return
|
66
76
|
end
|
67
77
|
|
68
78
|
print "nameservers (will request zone from first available):\n"
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
print "\n"
|
79
|
+
ns_answers = nspack.answer.select {|r| r.type == 'NS' }
|
80
|
+
ns_domain_names = ns_answers.map(&:domainname)
|
81
|
+
ns_domain_names.each { |name| puts "\t#{name}" }
|
82
|
+
puts ''
|
74
83
|
|
75
|
-
|
84
|
+
resolver.nameserver = ns_domain_names
|
76
85
|
|
77
86
|
zt = Dnsruby::ZoneTransfer.new
|
78
|
-
zt.server=
|
87
|
+
zt.server = ns_domain_names
|
88
|
+
|
79
89
|
zone = zt.transfer(domain) # , klass)
|
80
|
-
unless
|
81
|
-
|
82
|
-
return
|
90
|
+
unless zone
|
91
|
+
fatal_error("Zone transfer failed: #{resolver.errorstring}")
|
83
92
|
end
|
84
93
|
|
85
|
-
|
94
|
+
puts "checking PTR records"
|
86
95
|
check_ptr(domain, klass, zone)
|
87
|
-
print "\n"
|
88
96
|
|
89
|
-
|
97
|
+
puts "\nchecking NS records"
|
90
98
|
check_ns(domain, klass, zone)
|
91
|
-
print "\n"
|
92
99
|
|
93
|
-
|
100
|
+
puts "\nchecking MX records"
|
94
101
|
check_mx(domain, klass, zone)
|
95
|
-
print "\n"
|
96
102
|
|
97
|
-
|
103
|
+
puts "\nchecking CNAME records"
|
98
104
|
check_cname(domain, klass, zone)
|
99
105
|
print "\n"
|
100
106
|
|
101
|
-
if
|
102
|
-
|
107
|
+
if @recurse
|
108
|
+
puts 'checking subdomains'
|
103
109
|
subdomains = Hash.new
|
104
|
-
# foreach (grep { $_->type eq
|
105
|
-
|
110
|
+
# foreach (grep { $_->type eq 'NS' and $_->name ne $domain } @zone) {
|
111
|
+
zone.select { |i| i.type == 'NS' && i.name != domain }.each do |z|
|
106
112
|
subdomains[z.name] = 1
|
107
113
|
end
|
108
114
|
# foreach (sort keys %subdomains) {
|
109
115
|
subdomains.keys.sort.each do |k|
|
110
|
-
check_domain(k, klass)
|
116
|
+
check_domain([k, klass])
|
111
117
|
end
|
112
118
|
end
|
113
119
|
end
|
114
120
|
|
115
121
|
def check_ptr(domain, klass, zone)
|
116
|
-
|
117
|
-
# foreach $rr (grep { $_->type eq
|
118
|
-
|
122
|
+
resolver = Dnsruby::Resolver.new
|
123
|
+
# foreach $rr (grep { $_->type eq 'A' } @zone) {
|
124
|
+
zone.select { |z| z.type == 'A' }.each do |rr|
|
119
125
|
host = rr.name
|
120
126
|
addr = rr.address
|
121
|
-
ans= nil
|
127
|
+
ans = nil
|
122
128
|
begin
|
123
|
-
|
124
|
-
|
129
|
+
ans = resolver.query(addr.to_s, 'A') #, klass)
|
130
|
+
puts "\t#{host} (#{addr}) has no PTR record" if ans.header.ancount < 1
|
125
131
|
rescue Dnsruby::NXDomain
|
126
|
-
|
132
|
+
puts "\t#{host} (#{addr}) returns NXDomain"
|
127
133
|
end
|
128
134
|
end
|
129
135
|
end
|
130
136
|
|
131
137
|
def check_ns(domain, klass, zone)
|
132
|
-
|
138
|
+
resolver = Dnsruby::Resolver.new
|
133
139
|
# foreach $rr (grep { $_->type eq "NS" } @zone) {
|
134
|
-
|
135
|
-
ans =
|
136
|
-
|
140
|
+
zone.select { |z| z.type == 'NS' }.each do |rr|
|
141
|
+
ans = resolver.query(rr.nsdname, 'A', klass)
|
142
|
+
puts "\t", rr.nsdname, ' has no A record' if (ans.header.ancount < 1)
|
137
143
|
end
|
138
144
|
end
|
139
145
|
|
140
146
|
def check_mx(domain, klass, zone)
|
141
|
-
|
147
|
+
resolver = Dnsruby::Resolver.new
|
142
148
|
# foreach $rr (grep { $_->type eq "MX" } @zone) {
|
143
|
-
zone.select {|z| z.type ==
|
144
|
-
ans =
|
149
|
+
zone.select { |z| z.type == 'MX' }.each do |rr|
|
150
|
+
ans = resolver.query(rr.exchange, 'A', klass)
|
145
151
|
print "\t", rr.exchange, " has no A record\n" if (ans.header.ancount < 1)
|
146
152
|
end
|
147
153
|
end
|
148
154
|
|
149
155
|
def check_cname(domain, klass, zone)
|
150
|
-
|
156
|
+
resolver = Dnsruby::Resolver.new
|
151
157
|
# foreach $rr (grep { $_->type eq "CNAME" } @zone)
|
152
|
-
zone.select {|z| z.type ==
|
153
|
-
ans =
|
158
|
+
zone.select { |z| z.type == 'CNAME' }.each do |rr|
|
159
|
+
ans = resolver.query(rr.cname, 'A', klass)
|
154
160
|
print "\t", rr.cname, " has no A record\n" if (ans.header.ancount < 1)
|
155
161
|
end
|
156
162
|
end
|
157
163
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
+
def main
|
165
|
+
opts = GetoptLong.new(['-r', GetoptLong::NO_ARGUMENT])
|
166
|
+
@recurse = false
|
167
|
+
opts.each do |opt, arg|
|
168
|
+
case opt
|
169
|
+
when '-r'
|
170
|
+
@recurse = true
|
171
|
+
end
|
164
172
|
end
|
165
|
-
end
|
166
|
-
|
167
|
-
if (ARGV.length >=1 && ARGV.length <=2)
|
168
173
|
|
169
174
|
check_domain(ARGV)
|
170
|
-
exit
|
171
|
-
else
|
172
|
-
print "Usage: #{$0} [ -r ] domain [ class ]\n"
|
173
175
|
end
|
176
|
+
|
177
|
+
|
178
|
+
main
|
data/demo/digdlv.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
1
2
|
# --
|
2
3
|
# Copyright 2007 Nominet UK
|
3
4
|
#
|
@@ -40,46 +41,43 @@
|
|
40
41
|
# Michael Fuhr <mike@fuhr.org>
|
41
42
|
# Alex D <alexd@nominet.org.uk>
|
42
43
|
|
43
|
-
begin
|
44
|
-
require 'rubygems'
|
45
|
-
rescue LoadError
|
46
|
-
end
|
47
44
|
require 'dnsruby'
|
48
|
-
include Dnsruby
|
49
45
|
|
50
|
-
|
46
|
+
def fatal_error(message)
|
47
|
+
puts message
|
48
|
+
exit -1
|
49
|
+
end
|
51
50
|
|
51
|
+
unless (1..3).include?(ARGV.length)
|
52
|
+
fatal_error("Usage: #{$0} name [ type [ class ] ]")
|
53
|
+
end
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
+
resolver = Dnsruby::Recursor.new
|
56
|
+
zone_transfer = Dnsruby::ZoneTransfer.new
|
55
57
|
|
56
|
-
dlv_key = RR.create("dlv.isc.org. IN DNSKEY 257 3 5 BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2 brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5 ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt TDN0YUuWrBNh")
|
57
|
-
Dnssec.add_dlv_key(dlv_key)
|
58
|
+
dlv_key = Dnsruby::RR.create("dlv.isc.org. IN DNSKEY 257 3 5 BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2 brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5 ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt TDN0YUuWrBNh")
|
59
|
+
Dnsruby::Dnssec.add_dlv_key(dlv_key)
|
58
60
|
|
59
61
|
|
60
62
|
name, type, klass = ARGV
|
61
|
-
type ||=
|
62
|
-
klass ||=
|
63
|
+
type ||= 'A'
|
64
|
+
klass ||= 'IN'
|
63
65
|
|
64
|
-
if
|
65
|
-
rrs =
|
66
|
+
if type.upcase == 'AXFR'
|
67
|
+
rrs = zone_transfer.transfer(name) # , klass)
|
66
68
|
|
67
|
-
if
|
68
|
-
rrs.each
|
69
|
-
print rr.to_s + "\n"
|
70
|
-
end
|
69
|
+
if rrs
|
70
|
+
rrs.each { |rr| puts rr }
|
71
71
|
else
|
72
|
-
|
72
|
+
fatal_error("Zone transfer failed: #{resolver.errorstring}.")
|
73
73
|
end
|
74
74
|
|
75
75
|
else
|
76
76
|
|
77
|
-
# Dnsruby::TheLog.level=Logger::DEBUG
|
78
77
|
begin
|
79
|
-
answer =
|
80
|
-
answer
|
81
|
-
print answer
|
78
|
+
answer = resolver.query(name, type, klass)
|
79
|
+
puts answer
|
82
80
|
rescue Exception => e
|
83
|
-
|
81
|
+
fatal_error("query failed: #{e}")
|
84
82
|
end
|
85
83
|
end
|
data/demo/digroot.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
1
3
|
# --
|
2
4
|
# Copyright 2007 Nominet UK
|
3
5
|
#
|
@@ -35,29 +37,31 @@
|
|
35
37
|
# Michael Fuhr <mike@fuhr.org>
|
36
38
|
# Alex D <alexd@nominet.org.uk>
|
37
39
|
|
38
|
-
begin
|
39
|
-
require 'rubygems'
|
40
|
-
rescue LoadError
|
41
|
-
end
|
42
40
|
require 'dnsruby'
|
43
|
-
include Dnsruby
|
44
41
|
|
45
|
-
|
42
|
+
def fatal_error(message)
|
43
|
+
puts message
|
44
|
+
exit -1
|
45
|
+
end
|
46
|
+
|
47
|
+
unless (1..3).include?(ARGV.length)
|
48
|
+
fatal_error("Usage: #{$0} name [ type [ class ] ]")
|
49
|
+
end
|
50
|
+
|
46
51
|
|
47
|
-
|
48
|
-
|
49
|
-
|
52
|
+
inner_resolver = Dnsruby::Resolver.new
|
53
|
+
inner_resolver.do_validation = true
|
54
|
+
resolver = Dnsruby::Recursor.new(inner_resolver)
|
50
55
|
|
51
56
|
# Dnsruby::TheLog.level=Logger::DEBUG
|
52
57
|
|
53
58
|
name, type, klass = ARGV
|
54
|
-
type ||=
|
55
|
-
klass ||=
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
59
|
+
type ||= 'A'
|
60
|
+
klass ||= 'IN'
|
61
|
+
|
62
|
+
begin
|
63
|
+
answer = resolver.query(name, type, klass)
|
64
|
+
print answer
|
65
|
+
rescue Exception => e
|
66
|
+
fatal_error("query failed: #{e}")
|
67
|
+
end
|
data/demo/example_recurse.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
1
3
|
# --
|
2
4
|
# Copyright 2007 Nominet UK
|
3
5
|
#
|
@@ -19,11 +21,23 @@
|
|
19
21
|
|
20
22
|
require 'dnsruby'
|
21
23
|
|
22
|
-
|
24
|
+
unless (1..3).include?(ARGV.length)
|
25
|
+
puts "Usage: #{$0} domain [type [ class ]]"
|
26
|
+
exit(-1)
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
resolver = Dnsruby::Recursor.new
|
31
|
+
resolver.hints = '198.41.0.4' # A.ROOT-SERVER.NET.
|
32
|
+
|
33
|
+
|
23
34
|
Dnsruby::TheLog.level = Logger::DEBUG
|
35
|
+
|
36
|
+
|
24
37
|
name, type, klass = ARGV
|
25
|
-
type ||=
|
26
|
-
klass ||=
|
27
|
-
|
28
|
-
|
29
|
-
|
38
|
+
type ||= 'A'
|
39
|
+
klass ||= 'IN'
|
40
|
+
|
41
|
+
|
42
|
+
packet = resolver.query(name, type, klass)
|
43
|
+
puts packet
|
data/demo/mresolv.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
1
3
|
# --
|
2
4
|
# Copyright 2007 Nominet UK
|
3
5
|
#
|
@@ -29,12 +31,19 @@
|
|
29
31
|
#
|
30
32
|
# *-t timeout : Set the query timeout for each name in seconds.
|
31
33
|
|
34
|
+
# Examples for running:
|
35
|
+
#
|
36
|
+
# echo my-domain.com | ./mresolv.rb
|
37
|
+
# or
|
38
|
+
# ./mresolv.rb # then type domain name(s) separated by new lines and then ctrl-D
|
39
|
+
|
32
40
|
require 'dnsruby'
|
33
41
|
require 'getoptLong'
|
34
42
|
|
35
|
-
opts = GetoptLong.new(
|
36
|
-
[
|
37
|
-
[
|
43
|
+
opts = GetoptLong.new(
|
44
|
+
['-d', GetoptLong::NO_ARGUMENT],
|
45
|
+
['-n', GetoptLong::REQUIRED_ARGUMENT],
|
46
|
+
['-t', GetoptLong::REQUIRED_ARGUMENT])
|
38
47
|
|
39
48
|
max_outstanding = 32 # number of requests to have outstanding at any time
|
40
49
|
timeout = 15 # timeout (seconds)
|
@@ -42,7 +51,7 @@ debug = false
|
|
42
51
|
opts.each do |opt, arg|
|
43
52
|
case opt
|
44
53
|
when '-d'
|
45
|
-
Dnsruby.log.level=Logger::INFO
|
54
|
+
Dnsruby.log.level = Logger::INFO
|
46
55
|
debug = true
|
47
56
|
when '-n'
|
48
57
|
max_outstanding = arg.to_i
|
@@ -51,31 +60,34 @@ opts.each do |opt, arg|
|
|
51
60
|
end
|
52
61
|
end
|
53
62
|
|
54
|
-
|
55
|
-
|
63
|
+
resolver = Dnsruby::Resolver.new
|
64
|
+
resolver.query_timeout = timeout
|
65
|
+
|
56
66
|
# We want to have a rolling window of max_outstanding queries.
|
57
67
|
in_progress = 0
|
68
|
+
|
58
69
|
q = Queue.new
|
59
70
|
eof = false
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
71
|
+
|
72
|
+
until eof
|
73
|
+
# Have the thread loop round, send queries until max_num are outstanding.
|
74
|
+
while !eof && in_progress < max_outstanding
|
75
|
+
print('DEBUG: reading...') if debug
|
64
76
|
unless (name = gets)
|
65
77
|
print("EOF.\n") if debug
|
66
78
|
eof = true
|
67
79
|
break
|
68
80
|
end
|
69
81
|
name.chomp!
|
70
|
-
|
82
|
+
resolver.send_async(Dnsruby::Message.new(name), q, name)
|
71
83
|
in_progress += 1
|
72
84
|
print("name = #{name}, outstanding = #{in_progress}\n") if debug
|
73
85
|
end
|
74
|
-
#
|
75
|
-
while
|
86
|
+
# Keep receiving while the query pool is full, or the list has been queried
|
87
|
+
while in_progress >= max_outstanding || (eof && in_progress > 0)
|
76
88
|
id, result, error = q.pop
|
77
89
|
in_progress -= 1
|
78
|
-
if
|
90
|
+
if error
|
79
91
|
print("#{id}:\t#{error}\n")
|
80
92
|
else
|
81
93
|
print("#{result.answer.join("\n")}\n")
|