dnsruby 1.56.0 → 1.57.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3d4002c20d43d7fa849e81970e596e8b191a9290
4
- data.tar.gz: b1ebd40548471fd16a12616d3c834b9c30a8a26e
3
+ metadata.gz: c6d192a2471584058955bbdd453c5384567f8133
4
+ data.tar.gz: bc95f3527bfbab7ccc9f2861c3725dc86e5d9e6e
5
5
  SHA512:
6
- metadata.gz: 4f3f304b2f3ea1df07a0a24854e20a003f16964840800dae9ad574318369095ebec119ce7f074a3658564c530a84ec2f6a6a9a2b8fa2721aa4e6f329f982d6c3
7
- data.tar.gz: ab251ceaffa37db6a13eb2b7064c8cf16babdf15d75ef79d91de1e2140a7552b1759cb34f6d051bc649242396bce9edeadc758f51231a02be69788e55b036b44
6
+ metadata.gz: 408fd7d3242777cea4965ad97f8bf9f1c21677d604b0e6a68a5221f2fb6d9f2389a116936fb754f42f8bed8d4901f3ed87fab0fa67627af2d5fed8ac0426a190
7
+ data.tar.gz: 18b2bcfa91dc712faef28725394dcf3f89d154e4e0669b666d5bb3e553f29ed38f2d3bf2cca9b2dc5cd6d86c46059535dd0e2343af7ae0999cb3e9c263257e09
@@ -0,0 +1,2 @@
1
+ service_name: travis-ci
2
+ repo_token: 99b5l6CKFt3CC4rxYUetvDQvKtaTgCJW2
@@ -0,0 +1,24 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ .idea/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ *.bundle
20
+ *.so
21
+ *.o
22
+ *.a
23
+ mkmf.log
24
+ /nbproject/private/
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ cache: bundler
3
+ sudo: false
4
+
5
+ script: "bundle exec rake test"
6
+
7
+ rvm:
8
+ - 1.9.3
9
+ - 2.0.0
10
+ - 2.1.4
11
+ - jruby-19mode
12
+ # - rbx-2
13
+ - ruby-head
14
+ - jruby-head
15
+ # - ree
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.md CHANGED
@@ -5,8 +5,7 @@ Dnsruby
5
5
  =======
6
6
 
7
7
  Dnsruby is a pure Ruby DNS client library which implements a
8
- stub resolver. It aims to comply with all DNS RFCs, including
9
- DNSSEC NSEC3 support.
8
+ stub resolver. It aims to comply with all DNS RFCs.
10
9
 
11
10
  Dnsruby presents an enhanced API for DNS. It is based on Ruby's core
12
11
  resolv.rb Resolv API, but has been much extended to provide a
@@ -36,7 +35,7 @@ Dependencies
36
35
  Dnsruby can run with no dependencies. However, if you wish to
37
36
  use TSIG or DNSSEC then the OpenSSL library must be available.
38
37
  This is a part of the Ruby standard library, but appears not to
39
- be present on all Ruby platforms. If it is not available, then
38
+ be present on all Ruby platforms. If it is not available, then
40
39
  the test code will not run the tests which require it. Code which
41
40
  attempts to use the library (if it is not present) will raise an
42
41
  exception.
@@ -73,11 +72,6 @@ at runtime:
73
72
  bundle exec rake test
74
73
  ```
75
74
 
76
- Nominet operates a test server which the Dnsruby test code queries.
77
- If this server is not available then some of the online tests will
78
- not be run.
79
-
80
-
81
75
  Usage Help
82
76
  ----------
83
77
 
@@ -88,9 +82,12 @@ in understanding how to use Dnsruby:
88
82
  * http://blog.nominet.org.uk/tech/2009/05/21/examples-of-using-dnsruby-with-dnssec/
89
83
 
90
84
 
91
- Contact
85
+ Contact/Links
92
86
  -------
93
87
 
94
- alex@caerkettontech.com
95
- https://github.com/alexdalitz/dnsruby
96
-
88
+ | Link Type | Link/Text |
89
+ |-----|-----
90
+ | Author Email | alex@caerkettontech.com |
91
+ | Github | https://github.com/alexdalitz/dnsruby |
92
+ | Google Group | https://groups.google.com/forum/#!forum/dnsruby |
93
+ | Rubygems | http://rubygems.org/gems/dnsruby/ |
@@ -0,0 +1,100 @@
1
+ # Release Notes
2
+
3
+ ## v1.57.0
4
+
5
+ * Add query_raw method as alias for send_plain_message, with option to raise or return error.
6
+ * Fixed a bug in RR hash calculation where TTL should have been ignored but wasn't.
7
+ * Add support for (obsolete) GPOS resource record type.
8
+ * Tweak Travis CI configuration.
9
+ * Fix zone reader for case where a line contains whitespace preceding a comment.
10
+ * Add post install message.
11
+ * Improve README.
12
+ * Moved content of NEWS to RELEASE_NOTES.md.
13
+ * Use git ls-files now to determine files for inclusion in gem.
14
+
15
+
16
+ ## v1.56.0
17
+
18
+ * Drop support for Ruby 1.8, using lambda -> and hash 'key: value' notations.
19
+ * First release since the move from Rubyforge to Github (https://github.com/alexdalitz/dnsruby).
20
+ * Add EDNS client subnet support.
21
+ * Relocate CodeMapper subclasses, Resolv, RR, and RRSet classes.
22
+ * Add Travis CI and coveralls integration.
23
+ * Improve Google IPV6 support.
24
+ * Convert some file names to snake case.
25
+ * Remove trailing whitespace from lines, and ensure that comments have space between '#' and text.
26
+ * Restore test success when running under JRuby.
27
+ * Disabled attempt to connect to Nominet servers, which are no longer available.
28
+ * Convert from test/unit to minitest/autorun to support Ruby 2.1+.
29
+ * Remove setup.rb.
30
+ * Other minor refactoring and improvements to production code, test code, and documentation.
31
+
32
+
33
+ ## v1.53
34
+
35
+ * Validation routine fixes
36
+ * Ruby 1.9 fixes
37
+ * Recursor fixes
38
+ * IPv4 Regex fixes
39
+ * Fixes for A/PTR lookups with IP-like domain name
40
+ * TXT and SSHFP processing fixes
41
+ * Default retry parameters in Resolver more sensible
42
+
43
+
44
+ ## v1.48
45
+
46
+ * Fixed deadlock/performance issue seen on some platforms
47
+ * DNSSEC validation now disabled by default
48
+ * Signed root DS record can be added to validator
49
+ * ITAR support removed
50
+ * multi-line DS/RRSIG reading bug fixed (thanks Marco Davids!)
51
+ * DS algorithms of more than one digit can now be read from string
52
+ * LOC records now parsed correctly
53
+ * HINFO records now parsed correctly
54
+
55
+
56
+ ## v1.42
57
+
58
+ * Complicated TXT and NAPTR records now handled correctly
59
+ * ZoneReader now handles odd escape characters correctly
60
+ * Warns when immediate timeout occurs because no nameservers are configured
61
+ * Easy hmac-sha1/256 options to Resolver#tsig=
62
+ * ZoneReader fixed for "IN CNAME @" notations
63
+ * ZoneReader supports wildcards
64
+ * Dnsruby.version method added - currently returns 1.42
65
+
66
+
67
+ ## v1.41
68
+
69
+ * RFC3597 unknown classes (e.g. CLASS32) now handled correctly
70
+ in RRSIGs
71
+ * Resolver#do_caching flag added for Resolver-level caching
72
+ * DNSKEY#key_tag now cached - only recalculated when key data
73
+ changes
74
+ * Bugfix where Resolver would not time queries out if no
75
+ nameservers were configured
76
+ * Recursor now performs A and AAAA queries in parallel
77
+ * Fix for zero length salt
78
+ * Fixing priming for signed root
79
+ * Fixes for DLV verification
80
+ * Other minor fixes
81
+
82
+
83
+ ## v1.40
84
+
85
+ * Zone file reading support added (Dnsruby::ZoneReader)
86
+ * Name and Label speed-ups
87
+ * CodeMapper speed-ups
88
+ * DHCID RR added
89
+ * LOC presentation format parsing fixed
90
+ * KX RR added
91
+ * Quotations now allowed in text representation for ISDN, X25 and HINFO
92
+ * AFSDB from_string fixes
93
+ * Fixing CERT types and from_string
94
+ * CERT now allows algorithm 0
95
+ * Fix for DS record comparison
96
+ * HIP RR added
97
+ * Minor bug fixes
98
+ * IPSECKEY RR added
99
+ * Clients can now manipulate Name::Labels
100
+
@@ -0,0 +1,22 @@
1
+ Signed updates with Dnsruby
2
+ ===========================
3
+
4
+ In order to use TSIG records to automatically perform TSIG signing/verification of messages :
5
+
6
+ res = Dnsruby::Resolver.new("ns0.validation-test-servers.nominet.org.uk")
7
+
8
+ # Now configure the resolver with the TSIG key for signing/verifying
9
+ KEY_NAME="rubytsig"
10
+ KEY = "8n6gugn4aJ7MazyNlMccGKH1WxD2B3UvN/O/RA6iBupO2/03u9CTa3Ewz3gBWTSBCH3crY4Kk+tigNdeJBAvrw=="
11
+ res.tsig=KEY_NAME, KEY
12
+
13
+
14
+ # Now try sending/receiving some update messages
15
+ update = Dnsruby::Update.new("validation-test-servers.nominet.org.uk")
16
+ update_name = generate_update_name
17
+ update.absent(update_name)
18
+ update.add(update_name, 'TXT', 100, "test signed update")
19
+
20
+ # Resolver will automatically sign message and verify response
21
+ response = res.send_message(update)
22
+ assert(response.verified?) # Check that the response has been verified
@@ -0,0 +1,41 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'dnsruby/version'
4
+
5
+ SPEC = Gem::Specification.new do |s|
6
+ s.name = "dnsruby"
7
+ s.version = Dnsruby::VERSION
8
+ s.authors = ["Alex Dalitz"]
9
+ s.email = 'alex@caerkettontech.com'
10
+ s.homepage = "https://github.com/alexdalitz/dnsruby"
11
+ s.platform = Gem::Platform::RUBY
12
+ s.summary = "Ruby DNS(SEC) implementation"
13
+ s.description = \
14
+ 'Dnsruby is a pure Ruby DNS client library which implements a
15
+ stub resolver. It aims to comply with all DNS RFCs, including
16
+ DNSSEC NSEC3 support.'
17
+ s.license = "Apache License, Version 2.0"
18
+ s.files = `git ls-files -z`.split("\x0")
19
+
20
+ s.post_install_message = \
21
+ "Installing dnsruby...
22
+ For issues and source code: https://github.com/alexdalitz/dnsruby
23
+ For general discussion (please tell us how you use dnsruby): https://groups.google.com/forum/#!forum/dnsruby"
24
+
25
+ s.test_file = "test/ts_offline.rb"
26
+ s.has_rdoc = true
27
+ s.extra_rdoc_files = ["DNSSEC", "EXAMPLES", "README.md", "EVENTMACHINE"]
28
+
29
+ unless /java/ === RUBY_PLATFORM
30
+ s.add_development_dependency 'pry', '~> 0.10'
31
+ s.add_development_dependency 'pry-byebug', '~> 2.0' if RUBY_VERSION >= '2'
32
+ end
33
+
34
+ s.add_development_dependency 'rake', '~> 10', '>= 10.3.2'
35
+ s.add_development_dependency 'minitest', '~> 5.4'
36
+
37
+ if RUBY_VERSION >= "1.9.3"
38
+ s.add_development_dependency 'coveralls', '~> 0.7'
39
+ end
40
+ end
41
+
@@ -114,7 +114,7 @@ module Dnsruby
114
114
  @code = arg.code
115
115
  @string = array.values[@code]
116
116
  else
117
- raise ArgumentError.new("Unknown argument #{arg} for #{self.class}")
117
+ raise ArgumentError.new("Unknown argument of type #{arg.class}: #{arg} for #{self.class}")
118
118
  end
119
119
  end
120
120
 
@@ -18,9 +18,11 @@ class MessageDecoder #:nodoc: all
18
18
  @limit = @index + len
19
19
  d = yield(len)
20
20
  if @index < @limit
21
- raise DecodeError.new('junk exists')
21
+ message = "Junk exists; limit = #{@limit}, index = #{@index}"
22
+ raise DecodeError.new(message)
22
23
  elsif @limit < @index
23
- raise DecodeError.new('limit exceeded')
24
+ message = "Limit exceeded; limit = #{@limit}, index = #{@index}"
25
+ raise DecodeError.new(message)
24
26
  end
25
27
  @limit = save_limit
26
28
  d
@@ -264,6 +264,30 @@ module Dnsruby
264
264
  [response, error]
265
265
  end
266
266
 
267
+ # Sends a message with send_plain_message.
268
+ # Effectively a wrapper around send_plain_message, but adds
269
+ # the ability to configure whether an error will be raised
270
+ # or returned if it occurs.
271
+ #
272
+ # @param message the message to send to the DNS server
273
+ # @param error_strategy :return to return [response, error] (default),
274
+ # :raise to return response only, or raise an error if one occurs
275
+ def query_raw(message, error_strategy = :return)
276
+
277
+ unless [:return, :raise].include?(error_strategy)
278
+ raise ArgumentError.new('error_strategy should be one of [:return, :raise].')
279
+ end
280
+
281
+ response, error = send_plain_message(message)
282
+
283
+ if error_strategy == :return
284
+ [response, error]
285
+ else
286
+ raise error if error
287
+ response
288
+ end
289
+ end
290
+
267
291
  # This method takes a Message (supplied by the client), and sends it to
268
292
  # the configured nameservers. No changes are made to the Message before it
269
293
  # is sent (TSIG signatures will be applied if configured on the Resolver).
@@ -0,0 +1,187 @@
1
+ # encoding: ASCII-8BIT
2
+
3
+ module Dnsruby
4
+ class RR
5
+ # Class for Geographic Position (GPOS) resource records.
6
+ #
7
+ # RFC 1712 (https://www.ietf.org/rfc/rfc1712.txt)
8
+ class GPOS < RR
9
+
10
+ TypeValue = Types::GPOS
11
+ ClassValue = Classes::IN
12
+ ClassHash[[TypeValue, ClassValue]] = self #:nodoc: all
13
+
14
+ attr_accessor :longitude, :latitude, :altitude # NOTE: these are strings, not numbers
15
+
16
+ REQUIRED_KEYS = [:longitude, :latitude, :altitude]
17
+
18
+
19
+ # As with all resource record subclasses of RR, this class cannot be
20
+ # directly instantiated, but instead must be instantiated via use of
21
+ # one of the RR class methods. These GPOS class methods are wrappers
22
+ # around those RR methods, so that there is an interface on the GPOS
23
+ # class for creating GPOS instances.
24
+
25
+ # Create an instance from a hash of parameters, e.g.:
26
+ # {
27
+ # name: 'techhumans.com',
28
+ # type: Types::GPOS,
29
+ # ttl: 1234,
30
+ # longitude: '10.0',
31
+ # latitude: '20.0',
32
+ # altitude: '30.0',
33
+ # }
34
+ def self.from_hash(gpos_params_hash)
35
+ RR.new_from_hash(gpos_params_hash)
36
+ end
37
+
38
+
39
+ # Create an instance from a string containing parameters, e.g.:
40
+ # 'a.dnsruby.com. 10800 IN GPOS 10.0 20.0 30.0'
41
+ def self.from_string(gpos_params_string)
42
+ RR.new_from_string(gpos_params_string)
43
+ end
44
+
45
+
46
+ # Create an instance from an ordered parameter list, e.g.:
47
+ # EXAMPLE_GPOS_DATA = begin
48
+ # rdata = RR::GPOS.build_rdata(EXAMPLE_LONGITUDE, EXAMPLE_LATITUDE, EXAMPLE_ALTITUDE)
49
+ # [EXAMPLE_HOSTNAME, Types::GPOS, Classes::IN, EXAMPLE_TTL, rdata.length, rdata, 0]
50
+ # end
51
+ # self.from_data(*EXAMPLE_GPOS_DATA)
52
+ def self.from_data(*gpos_params_data)
53
+ RR.new_from_data(*gpos_params_data)
54
+ end
55
+
56
+
57
+ def from_data(array)
58
+ unless array.size == 3
59
+ raise "Array size for creating GPOS record must be 3 (long, lat, alt). Array was:\n#{array.inspect}"
60
+ end
61
+
62
+ from_hash({
63
+ longitude: array[0],
64
+ latitude: array[1],
65
+ altitude: array[2]
66
+ })
67
+ end
68
+
69
+ def from_hash(init_data)
70
+ self.class.validate_floats(init_data)
71
+ @longitude = init_data[:longitude].to_s
72
+ @latitude = init_data[:latitude].to_s
73
+ @altitude = init_data[:altitude].to_s
74
+ self.rdata = build_rdata
75
+ self
76
+ end
77
+
78
+ def from_string(string)
79
+ # Convert commas to spaces, then split by spaces:
80
+ from_data(string.gsub(',', ' ').split(' '))
81
+ end
82
+
83
+ # From the RFC:
84
+ # GPOS has the following format:
85
+ # <owner> <ttl> <class> GPOS <longitude> <latitude> <altitude>
86
+ #
87
+ # We handle the rdata, the RR superclass does the rest.
88
+ def rdata_to_string
89
+ [longitude, latitude, altitude].join(' ')
90
+ end
91
+
92
+ def encode_rdata(msg, _canonical)
93
+ msg.put_bytes(build_rdata)
94
+ end
95
+
96
+ def build_rdata
97
+ self.class.build_rdata(longitude, latitude, altitude)
98
+ end
99
+
100
+ def self.build_rdata(longitude, latitude, altitude)
101
+ binary_string = ''.force_encoding('ASCII-8BIT')
102
+
103
+ binary_string << longitude.length.chr
104
+ binary_string << longitude
105
+ binary_string << latitude.length.chr
106
+ binary_string << latitude
107
+ binary_string << altitude.length.chr
108
+ binary_string << altitude
109
+ binary_string
110
+ end
111
+
112
+ def self.decode_rdata(message)
113
+ rdata_s = message.get_bytes.clone
114
+
115
+ index = 0
116
+
117
+ long_len = rdata_s[index].ord; index += 1
118
+ longitude = rdata_s[index, long_len]; index += long_len
119
+
120
+ lat_len = rdata_s[index].ord; index += 1
121
+ latitude = rdata_s[index, lat_len]; index += lat_len
122
+
123
+ alt_len = rdata_s[index].ord; index += 1
124
+ altitude = rdata_s[index, alt_len]; index += alt_len
125
+
126
+ validate_latitude(latitude)
127
+ validate_longitude(longitude)
128
+
129
+ new([longitude, latitude, altitude].join(' ')) # e.g. "10.0 20.0 30.0"
130
+ end
131
+
132
+ # 'name' is used in the RR superclass, but 'owner' is the term referred to
133
+ # in the RFC, so we'll make owner an alias for name.
134
+ def owner
135
+ name
136
+ end
137
+
138
+ # 'name' is used in the RR superclass, but 'owner' is the term referred to
139
+ # in the RFC, so we'll make owner an alias for name.
140
+ def owner=(owner_string)
141
+ self.name = owner_string
142
+ end
143
+
144
+ def self.valid_float?(object)
145
+ begin
146
+ Float(object)
147
+ true
148
+ rescue
149
+ false
150
+ end
151
+ end
152
+
153
+ def self.validate_float_in_range(label, object, bound)
154
+ number = Float(object)
155
+ valid_range = (-Float(bound)..Float(bound))
156
+ unless valid_range.include?(number)
157
+ raise "Value of #{label} (#{number}) was not in the range #{valid_range}."
158
+ end
159
+ end
160
+
161
+ def self.validate_longitude(value)
162
+ validate_float_in_range('longitude', value, 180)
163
+ end
164
+
165
+ def self.validate_latitude(value)
166
+ validate_float_in_range('latitude', value, 90)
167
+ end
168
+
169
+ def self.validate_floats(init_data)
170
+ bad_float_keys = REQUIRED_KEYS.reject { |key| valid_float?(init_data[key]) }
171
+ unless bad_float_keys.empty?
172
+ message = "The following key value pair(s) do not have valid floats or float strings:\n"
173
+ bad_float_keys.each do |key|
174
+ message << "%:-12.12s => %s\n" % [init_data[key]]
175
+ end
176
+ raise message
177
+ end
178
+
179
+ validate_longitude(init_data[:longitude])
180
+ validate_latitude(init_data[:latitude])
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+
187
+
@@ -320,7 +320,6 @@ class RR
320
320
  end
321
321
 
322
322
  def ==(other)
323
-
324
323
  return false unless self.class == other.class
325
324
 
326
325
  ivars_to_compare = ->(object) do
@@ -351,7 +350,7 @@ class RR
351
350
  end
352
351
 
353
352
  def hash # :nodoc:
354
- vars = self.instance_variables - ['@ttl']
353
+ vars = (self.instance_variables - [:@ttl]).sort
355
354
  vars.inject(0) do |hash_value, var_name|
356
355
  hash_value ^ self.instance_variable_get(var_name).hash
357
356
  end
@@ -163,3 +163,4 @@ require 'dnsruby/resource/IPSECKEY'
163
163
  require 'dnsruby/resource/HIP'
164
164
  require 'dnsruby/resource/KX'
165
165
  require 'dnsruby/resource/DHCID'
166
+ require 'dnsruby/resource/GPOS'
@@ -1,3 +1,3 @@
1
1
  module Dnsruby
2
- VERSION = '1.56.0'
2
+ VERSION = '1.57.0'
3
3
  end
@@ -69,12 +69,11 @@ module Dnsruby
69
69
  # Returns a string representing the normalised line.
70
70
  def process_line(line, do_prefix_hack = false)
71
71
  return nil if (line[0,1] == ";")
72
+ line = strip_comments(line)
72
73
  return nil if (line.strip.length == 0)
73
74
  return nil if (!line || (line.length == 0))
74
75
  @in_quoted_section = false if !@continued_line
75
76
 
76
- line = strip_comments(line)
77
-
78
77
  if (line.index("$ORIGIN") == 0)
79
78
  @origin = line.split()[1].strip # $ORIGIN <domain-name> [<comment>]
80
79
  # print "Setting $ORIGIN to #{@origin}\n"
@@ -12,5 +12,6 @@ if ENV['RUN_EXTRA_TASK'] == 'TRUE'
12
12
  end
13
13
  end
14
14
 
15
+ require 'minitest'
15
16
  require 'minitest/autorun'
16
17
  require 'dnsruby'
@@ -0,0 +1,124 @@
1
+ require_relative 'spec_helper'
2
+
3
+ require_relative '../lib/dnsruby/resource/GPOS.rb'
4
+
5
+ include Dnsruby
6
+
7
+ # Tests GPOS resource record. See bottom of file for sample zone file.
8
+ class TestGPOS < Minitest::Test
9
+
10
+ EXAMPLE_LONGITUDE = '10.0'
11
+ EXAMPLE_LATITUDE = '20.0'
12
+ EXAMPLE_ALTITUDE = '30.0'
13
+ EXAMPLE_HOSTNAME = 'a.dnsruby.com.'
14
+ EXAMPLE_TTL = 3 * 60 * 60 # 10,800 seconds, or 3 hours
15
+
16
+ EXAMPLE_GPOS_STRING = 'a.dnsruby.com. 10800 IN GPOS 10.0 20.0 30.0'
17
+
18
+ EXAMPLE_GPOS_HASH = {
19
+ name: EXAMPLE_HOSTNAME,
20
+ type: Types::GPOS,
21
+ ttl: EXAMPLE_TTL,
22
+ longitude: EXAMPLE_LONGITUDE,
23
+ latitude: EXAMPLE_LATITUDE,
24
+ altitude: EXAMPLE_ALTITUDE,
25
+ }
26
+
27
+ EXAMPLE_GPOS_DATA = begin
28
+ rdata = RR::GPOS.build_rdata(EXAMPLE_LONGITUDE, EXAMPLE_LATITUDE, EXAMPLE_ALTITUDE)
29
+ [EXAMPLE_HOSTNAME, Types::GPOS, Classes::IN, EXAMPLE_TTL, rdata.length, rdata, 0]
30
+ end
31
+
32
+ # Returns a GPOS record returned by a BIND server configured with the zone file
33
+ # shown at the bottom of this file. I (keithrbennett) was unable to find a GPOS
34
+ # record on the public Internet to use for live testing.
35
+ def gpos_from_response
36
+ # query = Message.new(EXAMPLE_HOSTNAME, 'GPOS')
37
+ # query_binary = "E0\u0000\u0000\u0000\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0001a\adnsruby\u0003com\u0000\u0000\e\u0000\u0001"
38
+ # response, _error = Resolver.new('127.0.0.1').query_raw(query)
39
+
40
+ response_binary = "E0\x84\x80\x00\x01\x00\x01\x00\x01\x00\x01\x01a\adnsruby\x03com\x00\x00\e\x00\x01\xC0\f\x00\e\x00\x01\x00\x00*0\x00\x0F\x0410.0\x0420.0\x0430.0\xC0\x0E\x00\x02\x00\x01\x00\x00*0\x00\x06\x03ns1\xC0\x0E\xC0F\x00\x01\x00\x01\x00\x00*0\x00\x04\x7F\x00\x00\x01"
41
+ response = Message.decode(response_binary)
42
+
43
+ # response_binary = "\xE7\x01\x85\x90\x00\x01\x00\x01\x00\x01\x00\x01\x01g\adnsruby\x03com" +
44
+ # "\x00\x00\e\x00\x01\xC0\f\x00\e\x00\x01\x00\t:\x80\x00\x0F\x0420.0\x0430.0\x0410.0" +
45
+ # "\xC0\x0E\x00\x02\x00\x01\x00\t:\x80\x00\x05\x02ns\xC0\x0E\xC0F\x00\x01\x00\x01\x00" +
46
+ # "\t:\x80\x00\x04\xC0\xA8\x01\n"; nil
47
+ #
48
+ # response = Message.decode(response_binary)
49
+
50
+ response.answer[0]
51
+ end
52
+
53
+
54
+ def test_answer
55
+ answer = gpos_from_response
56
+ assert answer.is_a?(RR::GPOS), "Expected RR::GPOS but got a #{answer.class}: #{answer}"
57
+ assert_equal(EXAMPLE_LONGITUDE, answer.longitude)
58
+ assert_equal(EXAMPLE_LATITUDE, answer.latitude)
59
+ assert_equal(EXAMPLE_ALTITUDE, answer.altitude)
60
+ assert_equal(EXAMPLE_TTL, answer.ttl)
61
+ end
62
+
63
+
64
+ # should be: <owner> <ttl> <class> GPOS <longitude> <latitude> <altitude>
65
+ def test_to_s
66
+ actual = gpos_from_response.to_s.split
67
+ expected = %w(a.dnsruby.com. 10800 IN GPOS 10.0 20.0 30.0)
68
+ assert_equal(expected, actual)
69
+ end
70
+
71
+ def test_creation_approaches
72
+
73
+ ans_from_data = RR::GPOS.from_data(*EXAMPLE_GPOS_DATA)
74
+ ans_from_string = RR::GPOS.from_string(EXAMPLE_GPOS_STRING)
75
+ ans_from_hash = RR::GPOS.from_hash(EXAMPLE_GPOS_HASH)
76
+
77
+ fails_to_populate_rdata = []
78
+ fails_to_populate_rdata << 'data' if ans_from_data.rdata.nil?
79
+ fails_to_populate_rdata << 'string' if ans_from_string.rdata.nil?
80
+ fails_to_populate_rdata << 'hash' if ans_from_hash.rdata.nil?
81
+
82
+ assert_equal([], fails_to_populate_rdata,
83
+ "Populate modes failing to populate rdata: #{fails_to_populate_rdata.join(', ')}")
84
+
85
+ assert_equal(ans_from_data.rdata, ans_from_hash.rdata)
86
+ assert_equal(ans_from_data.rdata, ans_from_string.rdata)
87
+
88
+ assert_equal(ans_from_data, ans_from_hash)
89
+ assert_equal(ans_from_data, ans_from_string)
90
+ end
91
+
92
+ def test_decode_encode
93
+ response_binary = "E0\x84\x80\x00\x01\x00\x01\x00\x01\x00\x01\x01a\adnsruby\x03com\x00\x00\e\x00\x01\xC0\f\x00\e\x00\x01\x00\x00*0\x00\x0F\x0410.0\x0420.0\x0430.0\xC0\x0E\x00\x02\x00\x01\x00\x00*0\x00\x06\x03ns1\xC0\x0E\xC0F\x00\x01\x00\x01\x00\x00*0\x00\x04\x7F\x00\x00\x01"
94
+ message_object = Message.decode(response_binary)
95
+ reconstructed_binary = message_object.encode
96
+ assert_equal response_binary.force_encoding('ASCII-8BIT'), reconstructed_binary
97
+ end
98
+ end
99
+
100
+
101
+ # Sample zone file for setting up BIND to serve GPOS records:
102
+ =begin
103
+ $TTL 3h
104
+
105
+ @ IN SOA dnsruby.com. foo.dnsruby.com. (
106
+ 1 ; serial
107
+ 3H ; refresh after 3 hours
108
+ 1H ; retry after 1 hour
109
+ 1W ; expire after 1 week
110
+ 1H) ; negative caching TTL of 1 hour
111
+
112
+ dnsruby.com. IN NS ns1
113
+
114
+ ; Addresses for canonical names
115
+
116
+ ns1.dnsruby.com. IN A 127.0.0.1
117
+
118
+ a.dnsruby.com. IN A 2.4.6.8
119
+ IN GPOS 10.0 20.0 30.0
120
+
121
+ b.dnsruby.com. IN A 2.4.6.9
122
+ IN GPOS 40 50 60
123
+
124
+ =end
@@ -0,0 +1,25 @@
1
+ require_relative 'spec_helper'
2
+
3
+ include Dnsruby
4
+
5
+ class TestDNS < Minitest::Test
6
+
7
+ def setup
8
+ Dnsruby::Config.reset
9
+ end
10
+
11
+
12
+ # Illustrates that when a message whose class is 'HS' is sent to
13
+ # a DNS server that does not support the HS class, using send_plain_message,
14
+ # the response returns with an rcode of NOTIMP and a Dnsruby::NotImp error.
15
+ def test_hs_class_returns_notimp_code_and_error
16
+ resolver_host = 'a.gtld-servers.net'
17
+ resolver = Resolver.new(resolver_host)
18
+ message = Message.new('test.com', 'A', 'HS')
19
+ response, error = resolver.send_plain_message(message)
20
+
21
+ assert_equal(RCode::NOTIMP, response.rcode)
22
+ assert_equal(Dnsruby::NotImp, error.class)
23
+ end
24
+
25
+ end
@@ -134,9 +134,4 @@ class Nsec3Test < Minitest::Test
134
134
  rr = RR.create("929p027vb26s89h6fv5j7hmsis4tcr1p.tjeb.nl. 3600 IN NSEC3 1 0 5 beef 9rs4nbe7128ap5i6v196ge2iag5b7rcq A AAAA RRSIG
135
135
  ")
136
136
  end
137
-
138
- def test_rfc_examples
139
- print "IMPLEMENT NSEC3 validation!\n"
140
- return
141
- end
142
137
  end
@@ -285,4 +285,77 @@ class TestResolver < Minitest::Test
285
285
  def test_eventtype_api
286
286
  # @TODO@ TEST THE Resolver::EventType interface!
287
287
  end
288
- end
288
+ end
289
+
290
+
291
+ # Tests to see that query_raw handles send_plain_message's return values correctly.
292
+ class TestRawQuery < Minitest::Test
293
+
294
+ class CustomError < RuntimeError; end
295
+
296
+ # Returns a new resolver whose send_plain_message method always returns
297
+ # nil for the response, and a RuntimeError for the error.
298
+ def resolver_returning_error
299
+ resolver = Resolver.new
300
+ def resolver.send_plain_message(_message)
301
+ [nil, CustomError.new]
302
+ end
303
+ resolver
304
+ end
305
+
306
+ # Returns a new resolver whose send_plain_message is overridden to return
307
+ # :response_from_send_plain_message instead of a real Dnsruby::Message,
308
+ # for easy comparison in the tests.
309
+ def resolver_returning_response
310
+ resolver = Resolver.new
311
+ def resolver.send_plain_message(_message)
312
+ [:response_from_send_plain_message, nil]
313
+ end
314
+ resolver
315
+ end
316
+
317
+ # Test that when a strategy other than :raise or :return is passed,
318
+ # an ArgumentError is raised.
319
+ def test_bad_strategy
320
+ assert_raises(ArgumentError) do
321
+ resolver_returning_error.query_raw(Message.new, :invalid_strategy)
322
+ end
323
+ end
324
+
325
+ # Test that when send_plain_message returns an error,
326
+ # and the error strategy is :raise, query_raw raises an error.
327
+ def test_raise_error
328
+ assert_raises(CustomError) do
329
+ resolver_returning_error.query_raw(Message.new, :raise)
330
+ end
331
+ end
332
+
333
+ # Tests that if you don't specify an error strategy, an error will be
334
+ # returned rather than raised (i.e. strategy defaults to :return).
335
+ def test_return_error_is_default
336
+ _response, error = resolver_returning_error.query_raw(Message.new)
337
+ assert error.is_a?(CustomError)
338
+ end
339
+
340
+ # Tests that when no error is returned, no error is raised.
341
+ def test_raise_no_error
342
+ response, _error = resolver_returning_response.query_raw(Message.new, :raise)
343
+ assert_equal :response_from_send_plain_message, response
344
+ end
345
+
346
+ # Test that when send_plain_message returns an error, and the error strategy
347
+ # is set to :return, then an error is returned.
348
+ def test_return_error
349
+ _response, error = resolver_returning_error.query_raw(Message.new, :return)
350
+ assert error.is_a?(CustomError)
351
+ end
352
+
353
+ # Test that when send_plain_message returns a valid and response
354
+ # and nil error, the same are returned by query_raw.
355
+ def test_return_no_error
356
+ response, error = resolver_returning_response.query_raw(Message.new, :return)
357
+ assert_nil error
358
+ assert_equal :response_from_send_plain_message, response
359
+ end
360
+ end
361
+
@@ -20,6 +20,38 @@ require 'socket'
20
20
 
21
21
  include Dnsruby
22
22
  class TestRrOpt < Minitest::Test
23
+
24
+
25
+
26
+ # This test illustrates that when an OPT record specifying a maximum
27
+ # UDP size is added to a query, the server will respect that setting
28
+ # and limit the response's size to <= that maximum.
29
+ # This works only with send_plain_message, not send_message, query, etc.
30
+ def test_plain_respects_bufsize
31
+
32
+ resolver = Resolver.new('a.gtld-servers.net')
33
+
34
+ run_test = ->(bufsize) do
35
+
36
+ create_test_query = ->(bufsize) do
37
+ message = Message.new('com', Types.ANY, Classes.IN)
38
+ message.add_additional(RR::OPT.new(bufsize))
39
+ message
40
+ end
41
+
42
+ query = create_test_query.(bufsize)
43
+ response, _error = resolver.send_plain_message(query)
44
+ # puts "\nBufsize is #{bufsize}, binary message size is #{response.encode.size}"
45
+ assert_equal(true, response.header.tc)
46
+ assert(response.encode.size <= bufsize)
47
+ end
48
+
49
+ run_test.(512)
50
+ run_test.(612)
51
+ run_test.(4096)
52
+ end
53
+
54
+
23
55
  def test_rropt
24
56
  size=2048;
25
57
  ednsflags=0x9e22;
@@ -319,4 +319,13 @@ class TestRR < Minitest::Test
319
319
  # We should be here because the method should not have been found.
320
320
  end
321
321
  end
322
+
323
+ # TTL should be ignored when calculating the hash of an RR.
324
+ def test_hash_ignores_ttl
325
+ a1 = RR.new_from_string 'techhumans.com. 1111 IN A 69.89.31.97'
326
+ a2 = RR.new_from_string 'techhumans.com. 1111 IN A 69.89.31.97'
327
+ a3 = RR.new_from_string 'techhumans.com. 2222 IN A 69.89.31.97'
328
+ assert_equal a1.hash, a2.hash
329
+ assert_equal a1.hash, a3.hash
330
+ end
322
331
  end
@@ -18,6 +18,7 @@ require_relative 'spec_helper'
18
18
 
19
19
  Dnsruby.log.level = Logger::FATAL
20
20
 
21
+ require_relative 'tc_gpos.rb'
21
22
  require_relative 'tc_header.rb'
22
23
  require_relative "tc_name.rb"
23
24
  require_relative 'tc_message.rb'
@@ -40,6 +40,7 @@ if (online)
40
40
  print "It may just be that some UDP packets got lost the first time...\n"
41
41
  require_relative "tc_resolver.rb"
42
42
  require_relative "tc_dnsruby.rb"
43
+ require_relative "tc_hs.rb"
43
44
  # require_relative "tc_inet6.rb"
44
45
  # require_relative "tc_recurse.rb"
45
46
  require_relative "tc_tcp.rb"
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dnsruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.56.0
4
+ version: 1.57.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Dalitz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-25 00:00:00.000000000 Z
11
+ date: 2014-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry-byebug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: rake
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -71,11 +99,17 @@ extra_rdoc_files:
71
99
  - README.md
72
100
  - EVENTMACHINE
73
101
  files:
102
+ - ".coveralls.yml"
103
+ - ".gitignore"
104
+ - ".travis.yml"
74
105
  - DNSSEC
75
106
  - EVENTMACHINE
76
107
  - EXAMPLES
108
+ - Gemfile
77
109
  - README.md
110
+ - RELEASE_NOTES.md
78
111
  - Rakefile
112
+ - SIGNED_UPDATES
79
113
  - demo/axfr.rb
80
114
  - demo/check_soa.rb
81
115
  - demo/check_zone.rb
@@ -87,6 +121,7 @@ files:
87
121
  - demo/rubydig.rb
88
122
  - demo/to_resolve.txt
89
123
  - demo/trace_dns.rb
124
+ - dnsruby.gemspec
90
125
  - lib/dnsruby.rb
91
126
  - lib/dnsruby/DNS.rb
92
127
  - lib/dnsruby/cache.rb
@@ -117,6 +152,7 @@ files:
117
152
  - lib/dnsruby/resource/DLV.rb
118
153
  - lib/dnsruby/resource/DNSKEY.rb
119
154
  - lib/dnsruby/resource/DS.rb
155
+ - lib/dnsruby/resource/GPOS.rb
120
156
  - lib/dnsruby/resource/HINFO.rb
121
157
  - lib/dnsruby/resource/HIP.rb
122
158
  - lib/dnsruby/resource/IN.rb
@@ -169,11 +205,12 @@ files:
169
205
  - test/tc_dnsruby.rb
170
206
  - test/tc_ds.rb
171
207
  - test/tc_escapedchars.rb
208
+ - test/tc_gpos.rb
172
209
  - test/tc_hash.rb
173
210
  - test/tc_header.rb
174
211
  - test/tc_hip.rb
212
+ - test/tc_hs.rb
175
213
  - test/tc_ipseckey.rb
176
- - test/tc_keith.rb
177
214
  - test/tc_message.rb
178
215
  - test/tc_misc.rb
179
216
  - test/tc_name.rb
@@ -214,7 +251,10 @@ homepage: https://github.com/alexdalitz/dnsruby
214
251
  licenses:
215
252
  - Apache License, Version 2.0
216
253
  metadata: {}
217
- post_install_message:
254
+ post_install_message: |-
255
+ Installing dnsruby...
256
+ For issues and source code: https://github.com/alexdalitz/dnsruby
257
+ For general discussion (please tell us how you use dnsruby): https://groups.google.com/forum/#!forum/dnsruby
218
258
  rdoc_options: []
219
259
  require_paths:
220
260
  - lib
@@ -1,300 +0,0 @@
1
- # --
2
- # Copyright 2007 Nominet UK
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either tmexpress or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- # ++
16
- require_relative 'spec_helper'
17
-
18
- require 'socket'
19
-
20
- include Dnsruby
21
- # @TODO@ We also need a test server so we can control behaviour of server to test
22
- # different aspects of retry strategy.
23
- # Of course, with Ruby's limit of 256 open sockets per process, we'd need to run
24
- # the server in a different Ruby process.
25
-
26
- class TestResolver < Minitest::Test
27
-
28
- include Dnsruby
29
-
30
- Thread::abort_on_exception = true
31
-
32
- GOOD_DOMAIN_NAME = 'example.com'
33
- BAD_DOMAIN_NAME = 'dnsruby-test-of-bad-domain-name.blah'
34
-
35
- PORT = 42138
36
- @@port = PORT
37
-
38
- def setup
39
- Dnsruby::Config.reset
40
- end
41
-
42
- def assert_valid_response(response)
43
- assert(response.kind_of?(Message), "Expected response to be a message but was a #{response.class}")
44
- end
45
-
46
- def assert_nil_response(response)
47
- assert(response.nil?, "Expected no response but got a #{response.class}:\n#{response}")
48
- end
49
-
50
- def assert_error_is_exception(error, error_class = Exception)
51
- assert(error.is_a?(error_class), "Expected error to be an #{error_class}, but was a #{error.class}:\n#{error}")
52
- end
53
-
54
- def assert_nil_error(error)
55
- assert(error.nil?, "Expected no error but got a #{error.class}:\n#{error}")
56
- end
57
-
58
- def test_send_message
59
- response = Resolver.new.send_message(Message.new("example.com", Types.A))
60
- assert_valid_response(response)
61
- end
62
-
63
- def test_send_message_bang_noerror
64
- response, error = Resolver.new.send_message!(Message.new(GOOD_DOMAIN_NAME, Types.A))
65
- assert_nil_error(error)
66
- assert_valid_response(response)
67
- end
68
-
69
- def test_send_message_bang_error
70
- message = Message.new(BAD_DOMAIN_NAME, Types.A)
71
- response, error = Resolver.new.send_message!(message)
72
- assert_nil_response(response)
73
- assert_error_is_exception(error)
74
- end
75
-
76
- def test_send_plain_message
77
- resolver = Resolver.new
78
- response, error = resolver.send_plain_message(Message.new("cnn.com"))
79
- assert_nil_error(error)
80
- assert_valid_response(response)
81
-
82
- m = Message.new(BAD_DOMAIN_NAME)
83
- m.header.rd = true
84
- response, error = resolver.send_plain_message(m)
85
- assert_valid_response(response)
86
- assert_error_is_exception(error, NXDomain)
87
- end
88
-
89
- def test_query
90
- response = Resolver.new.query("example.com")
91
- assert_valid_response(response)
92
- end
93
-
94
- def test_query_bang_noerror
95
- response, error = Resolver.new.query!(GOOD_DOMAIN_NAME)
96
- assert_nil_error(error)
97
- assert_valid_response(response)
98
- end
99
-
100
- def test_query_bang_error
101
- response, error = Resolver.new.query!(BAD_DOMAIN_NAME)
102
- assert_nil_response(response)
103
- assert_error_is_exception(error)
104
- end
105
-
106
- def test_query_async
107
- q = Queue.new
108
- Resolver.new.send_async(Message.new("example.com", Types.A),q,q)
109
- id, response, error = q.pop
110
- assert_equal(id, q, "Id wrong!")
111
- assert_valid_response(response)
112
- assert_nil_error(error)
113
- end
114
-
115
- def test_query_one_duff_server_one_good
116
- res = Resolver.new({:nameserver => ["8.8.8.8", "8.8.8.7"]})
117
- res.retry_delay=1
118
- q = Queue.new
119
- res.send_async(Message.new("example.com", Types.A),q,q)
120
- id, response, error = q.pop
121
- assert_equal(id, q, "Id wrong!")
122
- assert_valid_response(response)
123
- assert_nil_error(error)
124
- end
125
-
126
- # @TODO@ Implement!! But then, why would anyone want to do this?
127
- # def test_many_threaded_clients
128
- # assert(false, "IMPLEMENT!")
129
- # end
130
-
131
- def test_reverse_lookup
132
- m = Message.new("8.8.8.8", Types.PTR)
133
- r = Resolver.new
134
- q=Queue.new
135
- r.send_async(m,q,q)
136
- id,ret, error=q.pop
137
- assert(ret.kind_of?(Message))
138
- no_pointer=true
139
- ret.each_answer do |answer|
140
- if (answer.type==Types.PTR)
141
- no_pointer=false
142
- assert(answer.domainname.to_s=~/google-public-dns/)
143
- end
144
- end
145
- assert(!no_pointer)
146
- end
147
-
148
- # def test_bad_host
149
- # res = Resolver.new({:nameserver => "localhost"})
150
- # res.retry_times=1
151
- # res.retry_delay=0
152
- # res.query_timeout = 1
153
- # q = Queue.new
154
- # res.send_async(Message.new("example.com", Types.A), q, q)
155
- # id, m, err = q.pop
156
- # assert(id==q)
157
- # assert(m == nil)
158
- # assert(err.kind_of?(OtherResolvError) || err.kind_of?(IOError), "OtherResolvError or IOError expected : got #{err.class}")
159
- # end
160
- #
161
- def test_nxdomain
162
- resolver = Resolver.new
163
- q = Queue.new
164
- resolver .send_async(Message.new(BAD_DOMAIN_NAME, Types.A), q, 1)
165
- id, m, error = q.pop
166
- assert(id==1, "Id should have been 1 but was #{id}")
167
- assert(m.rcode == RCode.NXDOMAIN, "Expected NXDOMAIN but got #{m.rcode} instead.")
168
- assert_error_is_exception(error, NXDomain)
169
- end
170
-
171
- def test_timeouts
172
- # test timeout behaviour for different retry, retrans, total timeout etc.
173
- # Problem here is that many sockets will be created for queries which time out.
174
- # Run a query which will not respond, and check that the timeout works
175
- if (!RUBY_PLATFORM=~/darwin/)
176
- start=stop=0
177
- retry_times = 3
178
- retry_delay=1
179
- packet_timeout=2
180
- # Work out what time should be, then time it to check
181
- expected = ((2**(retry_times-1))*retry_delay) + packet_timeout
182
- begin
183
- res = Resolver.new({:nameserver => "10.0.1.128"})
184
- # res = Resolver.new({:nameserver => "213.248.199.17"})
185
- res.packet_timeout=packet_timeout
186
- res.retry_times=retry_times
187
- res.retry_delay=retry_delay
188
- start=Time.now
189
- m = res.send_message(Message.new("a.t.dnsruby.validation-test-servers.nominet.org.uk", Types.A))
190
- fail
191
- rescue ResolvTimeout
192
- stop=Time.now
193
- time = stop-start
194
- assert(time <= expected *1.3 && time >= expected *0.9, "Wrong time take, expected #{expected}, took #{time}")
195
- end
196
- end
197
- end
198
-
199
- def test_packet_timeout
200
- res = Resolver.new({:nameserver => []})
201
- # res = Resolver.new({:nameserver => "10.0.1.128"})
202
- start=stop=0
203
- retry_times = retry_delay = packet_timeout= 10
204
- query_timeout=2
205
- begin
206
- res.packet_timeout=packet_timeout
207
- res.retry_times=retry_times
208
- res.retry_delay=retry_delay
209
- res.query_timeout=query_timeout
210
- # Work out what time should be, then time it to check
211
- expected = query_timeout
212
- start=Time.now
213
- m = res.send_message(Message.new("a.t.dnsruby.validation-test-servers.nominet.org.uk", Types.A))
214
- fail
215
- rescue ResolvTimeout
216
- stop=Time.now
217
- time = stop-start
218
- assert(time <= expected *1.3 && time >= expected *0.9, "Wrong time take, expected #{expected}, took #{time}")
219
- end #
220
- end
221
-
222
- def test_queue_packet_timeout
223
- # if (!RUBY_PLATFORM=~/darwin/)
224
- res = Resolver.new({:nameserver => "10.0.1.128"})
225
- # bad = SingleResolver.new("localhost")
226
- res.add_server("localhost")
227
- expected = 2
228
- res.query_timeout=expected
229
- q = Queue.new
230
- start = Time.now
231
- m = res.send_async(Message.new("a.t.dnsruby.validation-test-servers.nominet.org.uk", Types.A), q, q)
232
- id,ret,err = q.pop
233
- stop = Time.now
234
- assert(id=q)
235
- assert(ret==nil)
236
- assert(err.class == ResolvTimeout, "#{err.class}, #{err}")
237
- time = stop-start
238
- assert(time <= expected *1.3 && time >= expected *0.9, "Wrong time take, expected #{expected}, took #{time}")
239
- # end
240
- end
241
-
242
- def test_illegal_src_port
243
- # Also test all singleresolver ports ok
244
- # Try to set src_port to an illegal value - make sure error raised, and port OK
245
- res = Resolver.new
246
- res.port = 56789
247
- tests = [53, 387, 1265, 3210, 48619]
248
- tests.each do |bad_port|
249
- begin
250
- res.src_port = bad_port
251
- fail("bad port #{bad_port}")
252
- rescue
253
- end
254
- end
255
- assert(res.single_resolvers[0].src_port = 56789)
256
- end
257
-
258
- def test_add_src_port
259
- # Try setting and adding port ranges, and invalid ports, and 0.
260
- # Also test all singleresolver ports ok
261
- res = Resolver.new
262
- res.src_port = [56789,56790, 56793]
263
- assert(res.src_port == [56789,56790, 56793])
264
- res.src_port = 56889..56891
265
- assert(res.src_port == [56889,56890,56891])
266
- res.add_src_port(60000..60002)
267
- assert(res.src_port == [56889,56890,56891,60000,60001,60002])
268
- res.add_src_port([60004,60005])
269
- assert(res.src_port == [56889,56890,56891,60000,60001,60002,60004,60005])
270
- res.add_src_port(60006)
271
- assert(res.src_port == [56889,56890,56891,60000,60001,60002,60004,60005,60006])
272
- # Now test invalid src_ports
273
- tests = [0, 53, [60007, 53], [60008, 0], 55..100]
274
- tests.each do |x|
275
- begin
276
- res.add_src_port(x)
277
- fail()
278
- rescue
279
- end
280
- end
281
- assert(res.src_port == [56889,56890,56891,60000,60001,60002,60004,60005,60006])
282
- assert(res.single_resolvers[0].src_port == [56889,56890,56891,60000,60001,60002,60004,60005,60006])
283
- end
284
-
285
- def test_eventtype_api
286
- # @TODO@ TEST THE Resolver::EventType interface!
287
- end
288
-
289
- def test_rd_not_overwritten
290
- message = Message.new(GOOD_DOMAIN_NAME)
291
- message.header.rd = false
292
- assert(! message.header.rd)
293
- resolver = Resolver.new
294
- raise "Header rd flag was overwritten to true in #{__FILE__}:#{__LINE__}" if message.header.rd
295
- _response = resolver.send_message(message)
296
- puts "Header rd: #{message.header.rd}"
297
- raise "Header rd flag was overwritten to true in #{__FILE__}:#{__LINE__}" if message.header.rd
298
- assert(! message.header.rd, "Header rd flag was overwritten to true")
299
- end
300
- end