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