redns 0.1.17 → 0.2.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 +7 -0
- data/.travis.yml +8 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +20 -0
- data/README.md +31 -0
- data/Rakefile +2 -13
- data/VERSION +1 -1
- data/bin/redig +20 -13
- data/lib/redns.rb +32 -32
- data/lib/redns/address.rb +19 -19
- data/lib/redns/connection.rb +16 -16
- data/lib/redns/fragment.rb +5 -5
- data/lib/redns/message.rb +127 -127
- data/lib/redns/name.rb +35 -33
- data/lib/redns/question.rb +27 -27
- data/lib/redns/record/mx.rb +19 -19
- data/lib/redns/record/null.rb +27 -27
- data/lib/redns/record/soa.rb +49 -49
- data/lib/redns/resolver.rb +264 -262
- data/lib/redns/resource.rb +61 -61
- data/lib/redns/support.rb +41 -41
- data/redns.gemspec +26 -15
- data/test/test_redns_connection.rb +18 -6
- data/test/test_redns_fragment.rb +7 -7
- data/test/test_redns_message.rb +40 -40
- data/test/test_redns_name.rb +1 -1
- data/test/test_redns_question.rb +2 -2
- data/test/test_redns_resolver.rb +125 -119
- data/test/test_redns_resource.rb +32 -32
- metadata +43 -13
- data/README.rdoc +0 -17
data/lib/redns/resource.rb
CHANGED
@@ -3,12 +3,12 @@ class ReDNS::Resource < ReDNS::Fragment
|
|
3
3
|
|
4
4
|
# == Attributes ===========================================================
|
5
5
|
|
6
|
-
attribute :name, :
|
7
|
-
attribute :rclass, :
|
8
|
-
attribute :rtype, :
|
6
|
+
attribute :name, convert: ReDNS::Name, default: lambda { ReDNS::Name.new }
|
7
|
+
attribute :rclass, default: :in
|
8
|
+
attribute :rtype, default: :a
|
9
9
|
attribute :rdata
|
10
|
-
attribute :ttl, :
|
11
|
-
attribute :additional, :
|
10
|
+
attribute :ttl, default: 0, convert: :to_i
|
11
|
+
attribute :additional, default: lambda { [ ] }
|
12
12
|
|
13
13
|
# == Class Methods ========================================================
|
14
14
|
|
@@ -18,71 +18,71 @@ class ReDNS::Resource < ReDNS::Fragment
|
|
18
18
|
self.name.empty?
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
def to_s
|
22
|
+
"#{name} #{ttl} #{rclass.to_s.upcase} #{rtype.to_s.upcase} #{rdata}"
|
23
|
+
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
def to_a
|
26
|
+
[ name, ttl, rclass, rtype, rdata.to_a ].flatten
|
27
|
+
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
29
|
+
def serialize(buffer = ReDNS::Buffer.new)
|
30
|
+
self.name.serialize(buffer)
|
31
|
+
|
32
|
+
data_buffer = nil
|
33
|
+
|
34
|
+
if (self.rdata)
|
35
|
+
data_buffer = ReDNS::Buffer.new
|
36
|
+
self.rdata.serialize(data_buffer)
|
37
|
+
end
|
38
|
+
|
39
|
+
buffer.pack(
|
40
40
|
'nnNn',
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
41
|
+
ReDNS::RR_TYPE[self.rtype],
|
42
|
+
ReDNS::RR_CLASS[self.rclass],
|
43
|
+
self.ttl,
|
44
|
+
data_buffer ? data_buffer.length : 0
|
45
|
+
)
|
46
|
+
|
47
|
+
if (data_buffer)
|
48
|
+
buffer.append(data_buffer)
|
49
49
|
end
|
50
50
|
|
51
51
|
buffer
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
end
|
53
|
+
|
54
|
+
def deserialize(buffer)
|
55
|
+
self.name = ReDNS::Name.new(buffer)
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
raw = buffer.unpack("nnNn")
|
58
|
+
|
59
|
+
self.rtype = ReDNS::RR_TYPE_LABEL[raw.shift]
|
60
|
+
self.rclass = ReDNS::RR_CLASS_LABEL[raw.shift]
|
61
|
+
self.ttl = raw.shift
|
62
|
+
|
63
|
+
rdata_length = raw.shift
|
64
64
|
|
65
65
|
self.rdata =
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
66
|
+
case (self.rtype)
|
67
|
+
when :a, :aaaa
|
68
|
+
self.rdata = ReDNS::Address.new(buffer)
|
69
|
+
when :cname, :ptr, :ns
|
70
|
+
self.rdata = ReDNS::Name.new(buffer)
|
71
|
+
when :mx
|
72
|
+
self.rdata = ReDNS::Record::MX.new(buffer)
|
73
|
+
when :soa
|
74
|
+
self.rdata = ReDNS::Record::SOA.new(buffer)
|
75
|
+
when :null
|
76
|
+
self.rdata = (rdata_length and ReDNS::Record::Null.new(buffer.slice(rdata_length)))
|
77
|
+
when :spf
|
78
|
+
self.rdata = (rdata_length and ReDNS::Record::SPF.new(buffer.slice(rdata_length)))
|
79
|
+
when :txt
|
80
|
+
self.rdata = (rdata_length and ReDNS::Record::TXT.new(buffer.slice(rdata_length)))
|
81
|
+
else
|
82
82
|
# FUTURE: Throw exception here when trying to decode invalid type
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
|
86
|
+
self
|
87
87
|
end
|
88
88
|
end
|
data/lib/redns/support.rb
CHANGED
@@ -1,47 +1,47 @@
|
|
1
1
|
module ReDNS::Support
|
2
2
|
def addr_to_arpa(ip)
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
3
|
+
ip and (ip.split(/\./).reverse.join('.') + '.in-addr.arpa.')
|
4
|
+
end
|
5
|
+
|
6
|
+
def inet_ntoa(addr)
|
7
|
+
addr.unpack("C4")[0, 4].collect do |v|
|
8
|
+
v or 0
|
9
|
+
end.join('.')
|
10
|
+
end
|
11
|
+
|
12
|
+
def inet_aton(s)
|
13
|
+
s.split(/\./).map do |c|
|
14
|
+
c.to_i
|
15
|
+
end.pack("C*")
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
def io_nonblock?(io)
|
19
|
+
(io.fcntl(Fcntl::F_GETFL) & File::NONBLOCK) != 0
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
22
|
+
def io_set_nonblock(io, nb = true)
|
23
|
+
flags = io.fcntl(Fcntl::F_GETFL)
|
24
|
+
|
25
|
+
if (nb)
|
26
|
+
flags |= File::NONBLOCK
|
27
|
+
else
|
28
|
+
flags &= ~File::NONBLOCK
|
29
|
+
end
|
30
|
+
|
31
|
+
io.fcntl(Fcntl::F_SETFL, flags)
|
32
|
+
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
34
|
+
def io_nonblock(nb = true, &block)
|
35
|
+
flag = io_nonblock?(io)
|
36
|
+
|
37
|
+
io_set_nonblock(io, nb)
|
38
|
+
|
39
|
+
yield(block)
|
40
|
+
ensure
|
41
|
+
io_set_nonblock(io, flag)
|
42
|
+
end
|
43
|
+
|
44
|
+
def bind_all_addr
|
45
45
|
'0.0.0.0'
|
46
46
|
end
|
47
47
|
|
@@ -60,6 +60,6 @@ module ReDNS::Support
|
|
60
60
|
def default_resolver_address
|
61
61
|
ReDNS::Resolver.servers.first
|
62
62
|
end
|
63
|
-
|
64
|
-
|
63
|
+
|
64
|
+
extend(self)
|
65
65
|
end
|
data/redns.gemspec
CHANGED
@@ -2,23 +2,29 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: redns 0.2.0 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
|
-
s.name = "redns"
|
8
|
-
s.version = "0.
|
8
|
+
s.name = "redns".freeze
|
9
|
+
s.version = "0.2.0"
|
9
10
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
s.
|
15
|
-
s.
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib".freeze]
|
13
|
+
s.authors = ["tadman".freeze]
|
14
|
+
s.date = "2017-09-14"
|
15
|
+
s.description = "ReDNS is a pure Ruby DNS library with drivers for reactor-model engines such as EventMachine".freeze
|
16
|
+
s.email = "github@tadman.ca".freeze
|
17
|
+
s.executables = ["redig".freeze]
|
16
18
|
s.extra_rdoc_files = [
|
17
|
-
"
|
19
|
+
"LICENSE.txt",
|
20
|
+
"README.md"
|
18
21
|
]
|
19
22
|
s.files = [
|
20
23
|
".document",
|
21
|
-
"
|
24
|
+
".travis.yml",
|
25
|
+
"Gemfile",
|
26
|
+
"LICENSE.txt",
|
27
|
+
"README.md",
|
22
28
|
"Rakefile",
|
23
29
|
"VERSION",
|
24
30
|
"bin/redig",
|
@@ -53,18 +59,23 @@ Gem::Specification.new do |s|
|
|
53
59
|
"test/test_redns_resource.rb",
|
54
60
|
"test/test_redns_support.rb"
|
55
61
|
]
|
56
|
-
s.homepage = "http://github.com/tadman/redns"
|
57
|
-
s.
|
58
|
-
s.
|
59
|
-
s.summary = "Ruby Reactor-Ready DNS Library"
|
62
|
+
s.homepage = "http://github.com/tadman/redns".freeze
|
63
|
+
s.rubygems_version = "2.6.11".freeze
|
64
|
+
s.summary = "Ruby Reactor-Ready DNS Library".freeze
|
60
65
|
|
61
66
|
if s.respond_to? :specification_version then
|
62
|
-
s.specification_version =
|
67
|
+
s.specification_version = 4
|
63
68
|
|
64
69
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
70
|
+
s.add_runtime_dependency(%q<rake>.freeze, [">= 0"])
|
71
|
+
s.add_runtime_dependency(%q<eventmachine>.freeze, [">= 0"])
|
65
72
|
else
|
73
|
+
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
74
|
+
s.add_dependency(%q<eventmachine>.freeze, [">= 0"])
|
66
75
|
end
|
67
76
|
else
|
77
|
+
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
78
|
+
s.add_dependency(%q<eventmachine>.freeze, [">= 0"])
|
68
79
|
end
|
69
80
|
end
|
70
81
|
|
@@ -58,10 +58,10 @@ class TestReDNSConnection < Test::Unit::TestCase
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
assert_equal %w[
|
61
|
+
assert_equal %w[ 93.184.216.34 ], address.collect { |a| a.rdata.to_s }
|
62
62
|
assert_equal %w[ 43-10.any.icann.org. ], reverse.collect { |a| a.rdata.to_s }
|
63
63
|
assert_equal %w[ a.iana-servers.net. b.iana-servers.net. ], nameservers.collect { |a| a.rdata.to_s }.sort
|
64
|
-
assert_equal %w[
|
64
|
+
assert_equal %w[ 173.255.229.30 ], cname.collect { |a| a.rdata.to_s }
|
65
65
|
end
|
66
66
|
|
67
67
|
def test_simple_timeout
|
@@ -89,7 +89,7 @@ class TestReDNSConnection < Test::Unit::TestCase
|
|
89
89
|
c.timeout = nil
|
90
90
|
end
|
91
91
|
|
92
|
-
assert_equal ReDNS::Connection::
|
92
|
+
assert_equal ReDNS::Connection::TIMEOUT_DEFAULT, dns.timeout
|
93
93
|
|
94
94
|
EventMachine.stop_event_loop
|
95
95
|
end
|
@@ -100,9 +100,20 @@ class TestReDNSConnection < Test::Unit::TestCase
|
|
100
100
|
|
101
101
|
EventMachine.run do
|
102
102
|
dns = ReDNS::Connection.instance do |c|
|
103
|
-
c.nameservers
|
103
|
+
c.nameservers = %w[
|
104
|
+
127.0.0.254
|
105
|
+
127.0.0.253
|
106
|
+
127.0.0.252
|
107
|
+
127.0.0.251
|
108
|
+
127.0.0.250
|
109
|
+
127.0.0.249
|
110
|
+
127.0.0.248
|
111
|
+
127.0.0.247
|
112
|
+
127.0.0.246
|
113
|
+
127.0.0.245
|
114
|
+
] + c.nameservers
|
104
115
|
c.timeout = 1
|
105
|
-
c.attempts =
|
116
|
+
c.attempts = 20
|
106
117
|
end
|
107
118
|
|
108
119
|
dns.resolve('example.com') do |result|
|
@@ -113,6 +124,7 @@ class TestReDNSConnection < Test::Unit::TestCase
|
|
113
124
|
end
|
114
125
|
|
115
126
|
assert address
|
116
|
-
|
127
|
+
|
128
|
+
assert_equal '93.184.216.34', address.first.rdata.to_s
|
117
129
|
end
|
118
130
|
end
|
data/test/test_redns_fragment.rb
CHANGED
@@ -2,11 +2,11 @@ require File.expand_path('helper', File.dirname(__FILE__))
|
|
2
2
|
|
3
3
|
class ExampleFragment < ReDNS::Fragment
|
4
4
|
attribute :sample
|
5
|
-
attribute :sample_int, :
|
6
|
-
attribute :sample_proc, :
|
7
|
-
attribute :sample_class, :
|
8
|
-
attribute :sample_default, :
|
9
|
-
attribute :sample_boolean, :
|
5
|
+
attribute :sample_int, convert: :to_i, default: 0
|
6
|
+
attribute :sample_proc, convert: lambda { |v| v.to_i * 2 }
|
7
|
+
attribute :sample_class, convert: ReDNS::Buffer
|
8
|
+
attribute :sample_default, default: lambda { 5 }
|
9
|
+
attribute :sample_boolean, boolean: true
|
10
10
|
end
|
11
11
|
|
12
12
|
class TestReDNSFragment < Test::Unit::TestCase
|
@@ -46,8 +46,8 @@ class TestReDNSFragment < Test::Unit::TestCase
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def test_initialize_with_block
|
49
|
-
fragment = ExampleFragment.new do |
|
50
|
-
|
49
|
+
fragment = ExampleFragment.new do |f|
|
50
|
+
f.sample = "Example"
|
51
51
|
end
|
52
52
|
|
53
53
|
assert_equal "Example", fragment.sample
|
data/test/test_redns_message.rb
CHANGED
@@ -31,11 +31,11 @@ class TestReDNSMessage < Test::Unit::TestCase
|
|
31
31
|
|
32
32
|
def test_message_all_flags
|
33
33
|
message = ReDNS::Message.new(
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
authorative: true,
|
35
|
+
truncated: true,
|
36
|
+
recursion_desired: false,
|
37
|
+
recursion_available: true,
|
38
|
+
response_code: :server_failure
|
39
39
|
)
|
40
40
|
|
41
41
|
assert_equal true, message.query?
|
@@ -66,9 +66,9 @@ class TestReDNSMessage < Test::Unit::TestCase
|
|
66
66
|
def test_simple_query
|
67
67
|
message = ReDNS::Message.new
|
68
68
|
|
69
|
-
question = ReDNS::Question.new do |
|
70
|
-
|
71
|
-
|
69
|
+
question = ReDNS::Question.new do |q|
|
70
|
+
q.name = 'example.com'
|
71
|
+
q.qtype = :a
|
72
72
|
end
|
73
73
|
|
74
74
|
message.questions << question
|
@@ -78,38 +78,38 @@ class TestReDNSMessage < Test::Unit::TestCase
|
|
78
78
|
|
79
79
|
def test_encoded_fields
|
80
80
|
message = ReDNS::Message.new(
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
81
|
+
authorative: true,
|
82
|
+
truncated: true,
|
83
|
+
questions: [
|
84
|
+
ReDNS::Question.new(
|
85
|
+
name: 'example.com',
|
86
|
+
qtype: :a
|
87
|
+
)
|
88
|
+
],
|
89
|
+
answers: [
|
90
|
+
ReDNS::Resource.new(
|
91
|
+
name: 'example.com',
|
92
|
+
rtype: :a,
|
93
|
+
rdata: ReDNS::Address.new('1.2.3.4'),
|
94
|
+
ttl: 1234
|
95
|
+
)
|
96
|
+
],
|
97
|
+
nameservers: [
|
98
|
+
ReDNS::Resource.new(
|
99
|
+
name: 'example.com',
|
100
|
+
rtype: :ns,
|
101
|
+
rdata: ReDNS::Name.new('ns.example.com'),
|
102
|
+
ttl: 4321
|
103
|
+
)
|
104
|
+
],
|
105
|
+
additional_records: [
|
106
|
+
ReDNS::Resource.new(
|
107
|
+
name: 'ns.example.com',
|
108
|
+
rtype: :a,
|
109
|
+
rdata: ReDNS::Address.new('8.6.4.2'),
|
110
|
+
ttl: 9867
|
111
|
+
)
|
112
|
+
]
|
113
113
|
)
|
114
114
|
|
115
115
|
assert_equal ";; HEADER:\n;; opcode: QUERY status: NOERROR id: 1 \n;; flags: aa tc rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1\n;; QUESTION SECTION:\nexample.com. IN A\n;; ANSWER SECTION:\nexample.com. 1234 IN A 1.2.3.4\n;; NAMESERVER SECTION:\nexample.com. 4321 IN NS ns.example.com.\n;; ADDITIONAL SECTION:\nns.example.com. 9867 IN A 8.6.4.2\n", message.to_s
|