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 CHANGED
@@ -1 +1 @@
1
- 0.1.12
1
+ 0.1.13
@@ -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(0x10000) ^ (object_id ^ (Time.now.to_f * 100000).to_i)) % 0x10000
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 += 1
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
- pointer = (c & 0x3F << 8) | buffer.unpack('C')[0]
67
+ if (additional_offset = buffer.unpack('C')[0])
68
+ pointer = (c & 0x3F << 8) | additional_offset
63
69
 
64
- return_to_offset ||= buffer.offset
65
- buffer.rewind
66
- buffer.advance(pointer)
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
@@ -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
- self.contents = buffer.read(content_length)
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
@@ -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
- self.rdata = ReDNS::Record::Null.new(buffer.slice(rdata_length))
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.12"
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-05-16}
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.6.0}
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
@@ -1,4 +1,7 @@
1
1
  require File.expand_path('helper', File.dirname(__FILE__))
2
2
 
3
3
  class TestRedns < Test::Unit::TestCase
4
+ def test_module_loaded
5
+ assert ReDNS
6
+ end
4
7
  end
@@ -58,10 +58,10 @@ class TestReDNSConnection < Test::Unit::TestCase
58
58
  end
59
59
  end
60
60
 
61
- assert_equal %w[ 192.0.32.10 ], address
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
 
@@ -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
- 192, 6,
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
@@ -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.32.10', r[0].rdata.to_s
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.32.10', r.answers[0].rdata.to_s
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
- addrs = %w[
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.12
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-05-16 00:00:00 -04:00
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.6.0
82
+ rubygems_version: 1.5.3
83
83
  signing_key:
84
84
  specification_version: 3
85
85
  summary: Ruby Reactor-Ready DNS Library