redns 0.1.12 → 0.1.13
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.
- data/VERSION +1 -1
- data/lib/redns/connection.rb +5 -1
- data/lib/redns/message.rb +21 -2
- data/lib/redns/name.rb +23 -4
- data/lib/redns/record/null.rb +3 -3
- data/lib/redns/resource.rb +1 -1
- data/redns.gemspec +3 -3
- data/test/test_redns.rb +3 -0
- data/test/test_redns_connection.rb +4 -4
- data/test/test_redns_name.rb +14 -1
- data/test/test_redns_resolver.rb +23 -23
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.13
|
data/lib/redns/connection.rb
CHANGED
@@ -4,6 +4,7 @@ class ReDNS::Connection < EventMachine::Connection
|
|
4
4
|
# == Constants ============================================================
|
5
5
|
|
6
6
|
DEFAULT_TIMEOUT = 5
|
7
|
+
SEQUENCE_LIMIT = 0x10000
|
7
8
|
|
8
9
|
# == Properties ===========================================================
|
9
10
|
|
@@ -15,6 +16,8 @@ class ReDNS::Connection < EventMachine::Connection
|
|
15
16
|
|
16
17
|
# == Class Methods ========================================================
|
17
18
|
|
19
|
+
# Returns a new instance of a reactor-bound resolver. If a block is given,
|
20
|
+
# the instance is supplied for customization purposes.
|
18
21
|
def self.instance
|
19
22
|
connection = EventMachine.open_datagram_socket(
|
20
23
|
ReDNS::Support.bind_all_addr,
|
@@ -32,7 +35,7 @@ class ReDNS::Connection < EventMachine::Connection
|
|
32
35
|
def post_init
|
33
36
|
# Sequence numbers do not have to be cryptographically secure, but having
|
34
37
|
# a healthy amount of randomness is a good thing.
|
35
|
-
@sequence = (rand(
|
38
|
+
@sequence = (rand(SEQUENCE_LIMIT) ^ (object_id ^ (Time.now.to_f * SEQUENCE_LIMIT).to_i)) % SEQUENCE_LIMIT
|
36
39
|
|
37
40
|
# Callback tracking is done by matching response IDs in a lookup table
|
38
41
|
@callback = { }
|
@@ -97,6 +100,7 @@ class ReDNS::Connection < EventMachine::Connection
|
|
97
100
|
end
|
98
101
|
|
99
102
|
@sequence += 1
|
103
|
+
@sequence %= SEQUENCE_LIMIT
|
100
104
|
end
|
101
105
|
|
102
106
|
def unbind
|
data/lib/redns/message.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class ReDNS::Message < ReDNS::Fragment
|
2
2
|
# == Constants ============================================================
|
3
3
|
|
4
|
-
SECTIONS = [ :questions, :answers, :nameservers, :additional_records ]
|
4
|
+
SECTIONS = [ :questions, :answers, :nameservers, :additional_records ].freeze
|
5
5
|
|
6
6
|
# == Attributes ===========================================================
|
7
7
|
|
@@ -28,6 +28,9 @@ class ReDNS::Message < ReDNS::Fragment
|
|
28
28
|
|
29
29
|
# == Class Methods ========================================================
|
30
30
|
|
31
|
+
# Constructs a question that asks for more information about a given
|
32
|
+
# resource with an optional query type specified. Query type defaults to
|
33
|
+
# :ptr for dotted-quad IP addresses, :a otherwise.
|
31
34
|
def self.question(name, qtype = nil)
|
32
35
|
if (!qtype)
|
33
36
|
if (ReDNS::Support.is_ip?(name))
|
@@ -55,13 +58,17 @@ class ReDNS::Message < ReDNS::Fragment
|
|
55
58
|
# == Instance Methods =====================================================
|
56
59
|
|
57
60
|
def increment_id!
|
58
|
-
self.id
|
61
|
+
self.id = (self.id + 1) % 0x10000
|
59
62
|
end
|
60
63
|
|
64
|
+
# Returns true if this is a response type message, false otherwise, as is
|
65
|
+
# the case with query messages.
|
61
66
|
def response?
|
62
67
|
!self.query?
|
63
68
|
end
|
64
69
|
|
70
|
+
# Returns a string representation of the message in a format similar to what
|
71
|
+
# the dig shell utility produces.
|
65
72
|
def to_s
|
66
73
|
flags = [ ]
|
67
74
|
flags << 'qr' if (response?)
|
@@ -83,10 +90,13 @@ class ReDNS::Message < ReDNS::Fragment
|
|
83
90
|
additional_records.collect(&:to_s).join("\n") + "\n"
|
84
91
|
end
|
85
92
|
|
93
|
+
# Returns the length of the encoded DNS request.
|
86
94
|
def length
|
87
95
|
to_dns.length
|
88
96
|
end
|
89
97
|
|
98
|
+
# Returns true if the questions, answers, nameservers and additional records
|
99
|
+
# are all empty, false otherwise.
|
90
100
|
def empty?
|
91
101
|
questions.empty? and
|
92
102
|
answers.empty? and
|
@@ -94,10 +104,13 @@ class ReDNS::Message < ReDNS::Fragment
|
|
94
104
|
additional_records.empty?
|
95
105
|
end
|
96
106
|
|
107
|
+
# Returns a YAML serialized version of the message.
|
97
108
|
def to_yaml
|
98
109
|
@attributes.to_yaml
|
99
110
|
end
|
100
111
|
|
112
|
+
# Serializes the message into a supplied buffer, or allocates a new one to
|
113
|
+
# store it. Returns the buffer used.
|
101
114
|
def serialize(buffer = ReDNS::Buffer.new)
|
102
115
|
buffer.pack(
|
103
116
|
'nnnnnn',
|
@@ -126,11 +139,17 @@ class ReDNS::Message < ReDNS::Fragment
|
|
126
139
|
buffer
|
127
140
|
end
|
128
141
|
|
142
|
+
# Extracts a message from the supplied buffer. Will return the message if
|
143
|
+
# successful, nil if an error occurred or no suitable data cound be found
|
144
|
+
# in the buffer.
|
129
145
|
def deserialize(buffer)
|
130
146
|
return unless (buffer)
|
131
147
|
|
132
148
|
data = buffer.unpack("nnnnnn")
|
133
149
|
|
150
|
+
# Abandon efforts to decode if insufficient data is available.
|
151
|
+
return if (data.length < 6)
|
152
|
+
|
134
153
|
self.id = data.shift
|
135
154
|
|
136
155
|
flags = data.shift
|
data/lib/redns/name.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
class ReDNS::Name < ReDNS::Fragment
|
2
|
+
# == Constants ============================================================
|
3
|
+
|
4
|
+
POINTER_CHAIN_LIMIT = 64
|
5
|
+
|
2
6
|
# == Attributes ===========================================================
|
3
7
|
|
4
8
|
attribute :name, :default => '.'
|
@@ -52,6 +56,7 @@ class ReDNS::Name < ReDNS::Fragment
|
|
52
56
|
self.name = ''
|
53
57
|
|
54
58
|
return_to_offset = nil
|
59
|
+
pointer_count = 0
|
55
60
|
|
56
61
|
while (c = buffer.unpack('C')[0])
|
57
62
|
if (c & 0xC0 == 0xC0)
|
@@ -59,11 +64,25 @@ class ReDNS::Name < ReDNS::Fragment
|
|
59
64
|
# point and read from there, but preserve the position where the
|
60
65
|
# pointer was found to leave the buffer in that final state.
|
61
66
|
|
62
|
-
|
67
|
+
if (additional_offset = buffer.unpack('C')[0])
|
68
|
+
pointer = (c & 0x3F << 8) | additional_offset
|
63
69
|
|
64
|
-
|
65
|
-
|
66
|
-
|
70
|
+
return_to_offset ||= buffer.offset
|
71
|
+
buffer.rewind
|
72
|
+
buffer.advance(pointer)
|
73
|
+
|
74
|
+
pointer_count += 1
|
75
|
+
|
76
|
+
if (pointer_count > POINTER_CHAIN_LIMIT)
|
77
|
+
# Encountered too many pointers, probably a sign of a circular
|
78
|
+
# reference or a badly constructed response. Ignore.
|
79
|
+
break
|
80
|
+
end
|
81
|
+
else
|
82
|
+
# The buffer may have prematurely run dry, in which case the only
|
83
|
+
# option left is to abandon further processing.
|
84
|
+
break
|
85
|
+
end
|
67
86
|
elsif (c == 0)
|
68
87
|
break
|
69
88
|
else
|
data/lib/redns/record/null.rb
CHANGED
@@ -24,9 +24,9 @@ class ReDNS::Record::Null < ReDNS::Fragment
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def deserialize(buffer)
|
27
|
-
content_length = buffer.unpack('C')[0]
|
28
|
-
|
29
|
-
|
27
|
+
if (content_length = buffer.unpack('C')[0])
|
28
|
+
self.contents = buffer.read(content_length)
|
29
|
+
end
|
30
30
|
|
31
31
|
self
|
32
32
|
end
|
data/lib/redns/resource.rb
CHANGED
@@ -71,7 +71,7 @@ class ReDNS::Resource < ReDNS::Fragment
|
|
71
71
|
when :soa
|
72
72
|
self.rdata = ReDNS::Record::SOA.new(buffer)
|
73
73
|
when :txt, :null
|
74
|
-
|
74
|
+
self.rdata = (rdata_length and ReDNS::Record::Null.new(buffer.slice(rdata_length)))
|
75
75
|
when :mx
|
76
76
|
self.rdata = ReDNS::Record::MX.new(buffer)
|
77
77
|
else
|
data/redns.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{redns}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.13"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["tadman"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-06-17}
|
13
13
|
s.description = %q{ReDNS is a pure Ruby DNS library with drivers for reactor-model engines such as EventMachine}
|
14
14
|
s.email = %q{github@tadman.ca}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -51,7 +51,7 @@ Gem::Specification.new do |s|
|
|
51
51
|
]
|
52
52
|
s.homepage = %q{http://github.com/tadman/redns}
|
53
53
|
s.require_paths = ["lib"]
|
54
|
-
s.rubygems_version = %q{1.
|
54
|
+
s.rubygems_version = %q{1.5.3}
|
55
55
|
s.summary = %q{Ruby Reactor-Ready DNS Library}
|
56
56
|
s.test_files = [
|
57
57
|
"test/helper.rb",
|
data/test/test_redns.rb
CHANGED
@@ -58,10 +58,10 @@ class TestReDNSConnection < Test::Unit::TestCase
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
assert_equal %w[ 192.0.
|
62
|
-
assert_equal %w[ www.example.com. ], reverse
|
63
|
-
assert_equal %w[ a.iana-servers.net. b.iana-servers.net. ], nameservers.sort
|
64
|
-
assert_equal %w[ 74.207.228.18 ], cname
|
61
|
+
assert_equal %w[ 192.0.43.10 ], address.collect { |a| a.rdata.to_s }
|
62
|
+
assert_equal %w[ www.example.com. ], reverse.collect { |a| a.rdata.to_s }
|
63
|
+
assert_equal %w[ a.iana-servers.net. b.iana-servers.net. ], nameservers.collect { |a| a.rdata.to_s }.sort
|
64
|
+
assert_equal %w[ 74.207.228.18 ], cname.collect { |a| a.rdata.to_s }
|
65
65
|
|
66
66
|
end
|
67
67
|
|
data/test/test_redns_name.rb
CHANGED
@@ -86,7 +86,7 @@ class TestReDNSName < Test::Unit::TestCase
|
|
86
86
|
example_buffer = ReDNS::Buffer.new(
|
87
87
|
[
|
88
88
|
3, ?c, ?o, ?m,
|
89
|
-
|
89
|
+
0xC0, 6,
|
90
90
|
3, ?n, ?e, ?t,
|
91
91
|
0,
|
92
92
|
7, ?e, ?x, ?a, ?m, ?p, ?l, ?e,
|
@@ -105,4 +105,17 @@ class TestReDNSName < Test::Unit::TestCase
|
|
105
105
|
|
106
106
|
assert_equal 0, example_buffer.length
|
107
107
|
end
|
108
|
+
|
109
|
+
def test_circular_pointer
|
110
|
+
example_buffer = ReDNS::Buffer.new(
|
111
|
+
[
|
112
|
+
3, ?c, ?o, ?m,
|
113
|
+
0xC0, 0
|
114
|
+
].collect(&:chr).join
|
115
|
+
)
|
116
|
+
|
117
|
+
name = ReDNS::Name.new(example_buffer)
|
118
|
+
|
119
|
+
assert_equal 'com.' * (ReDNS::Name::POINTER_CHAIN_LIMIT + 1), name.to_s
|
120
|
+
end
|
108
121
|
end
|
data/test/test_redns_resolver.rb
CHANGED
@@ -25,7 +25,7 @@ class TestReReDNSResolver < Test::Unit::TestCase
|
|
25
25
|
assert_equal 1, r.size
|
26
26
|
|
27
27
|
assert_equal :a, r[0].rtype
|
28
|
-
assert_equal '192.0.
|
28
|
+
assert_equal '192.0.43.10', r[0].rdata.to_s
|
29
29
|
end
|
30
30
|
|
31
31
|
def test_simple_reverse_query
|
@@ -63,7 +63,7 @@ class TestReReDNSResolver < Test::Unit::TestCase
|
|
63
63
|
assert_equal 1, r.questions.size
|
64
64
|
assert_equal 1, r.answers.size
|
65
65
|
|
66
|
-
assert_equal '192.0.
|
66
|
+
assert_equal '192.0.43.10', r.answers[0].rdata.to_s
|
67
67
|
end
|
68
68
|
|
69
69
|
def test_ns_query
|
@@ -87,12 +87,12 @@ class TestReReDNSResolver < Test::Unit::TestCase
|
|
87
87
|
|
88
88
|
def test_bulk_query
|
89
89
|
addrs = %w[
|
90
|
-
192.0.32.1
|
91
|
-
192.0.32.2
|
92
|
-
192.0.32.3
|
93
|
-
192.0.32.4
|
94
|
-
192.0.32.5
|
95
90
|
192.0.32.10
|
91
|
+
192.0.32.12
|
92
|
+
192.0.32.13
|
93
|
+
192.0.32.14
|
94
|
+
192.0.32.15
|
95
|
+
192.0.32.16
|
96
96
|
].collect do |i|
|
97
97
|
ReDNS::Support.addr_to_arpa(i)
|
98
98
|
end
|
@@ -110,12 +110,12 @@ class TestReReDNSResolver < Test::Unit::TestCase
|
|
110
110
|
assert rlist[addrs[0]]
|
111
111
|
|
112
112
|
expected = %w[
|
113
|
-
32-1.lax.icann.org.
|
114
|
-
32-2.lax.icann.org.
|
115
|
-
32-3.lax.icann.org.
|
116
|
-
32-4.lax.icann.org.
|
117
|
-
32-5.lax.icann.org.
|
118
113
|
www.example.com.
|
114
|
+
redirects.iana.org.
|
115
|
+
tools.iana.org.
|
116
|
+
nomcom.icann.org.
|
117
|
+
confirm.icann.org.
|
118
|
+
dnscert.com.
|
119
119
|
]
|
120
120
|
|
121
121
|
answers = addrs.collect do |a|
|
@@ -126,13 +126,13 @@ class TestReReDNSResolver < Test::Unit::TestCase
|
|
126
126
|
end
|
127
127
|
|
128
128
|
def test_reverse_addresses
|
129
|
-
|
130
|
-
192.0.32.1
|
131
|
-
192.0.32.2
|
132
|
-
192.0.32.3
|
133
|
-
192.0.32.4
|
134
|
-
192.0.32.5
|
129
|
+
addrs = %w[
|
135
130
|
192.0.32.10
|
131
|
+
192.0.32.12
|
132
|
+
192.0.32.13
|
133
|
+
192.0.32.14
|
134
|
+
192.0.32.15
|
135
|
+
192.0.32.16
|
136
136
|
]
|
137
137
|
|
138
138
|
res = ReDNS::Resolver.new
|
@@ -144,12 +144,12 @@ class TestReReDNSResolver < Test::Unit::TestCase
|
|
144
144
|
assert_equal addrs.length, rlist.length
|
145
145
|
|
146
146
|
expected = %w[
|
147
|
-
32-1.lax.icann.org.
|
148
|
-
32-2.lax.icann.org.
|
149
|
-
32-3.lax.icann.org.
|
150
|
-
32-4.lax.icann.org.
|
151
|
-
32-5.lax.icann.org.
|
152
147
|
www.example.com.
|
148
|
+
redirects.iana.org.
|
149
|
+
tools.iana.org.
|
150
|
+
nomcom.icann.org.
|
151
|
+
confirm.icann.org.
|
152
|
+
dnscert.com.
|
153
153
|
]
|
154
154
|
|
155
155
|
answers = addrs.collect do |a|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: redns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.1.
|
5
|
+
version: 0.1.13
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- tadman
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-06-17 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -79,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements: []
|
80
80
|
|
81
81
|
rubyforge_project:
|
82
|
-
rubygems_version: 1.
|
82
|
+
rubygems_version: 1.5.3
|
83
83
|
signing_key:
|
84
84
|
specification_version: 3
|
85
85
|
summary: Ruby Reactor-Ready DNS Library
|