dnsruby 1.58.0 → 1.59.0
Sign up to get free protection for your applications and to get access to all the features.
- 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")
|