redns 0.1.17 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|