net-dns 0.8.0 → 0.9.0

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.
Files changed (64) hide show
  1. checksums.yaml +6 -14
  2. data/.gitignore +1 -1
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +3 -0
  5. data/.rubocop_defaults.yml +364 -0
  6. data/.rubocop_todo.yml +207 -0
  7. data/.travis.yml +9 -16
  8. data/CHANGELOG.md +12 -1
  9. data/Gemfile +6 -2
  10. data/LICENSE.txt +56 -0
  11. data/README.md +94 -77
  12. data/Rakefile +23 -56
  13. data/bin/console +14 -0
  14. data/demo/check_soa.rb +27 -38
  15. data/demo/threads.rb +3 -7
  16. data/lib/net/dns.rb +4 -11
  17. data/lib/net/dns/core_ext.rb +8 -15
  18. data/lib/net/dns/header.rb +58 -66
  19. data/lib/net/dns/names.rb +25 -23
  20. data/lib/net/dns/packet.rb +136 -139
  21. data/lib/net/dns/question.rb +36 -39
  22. data/lib/net/dns/resolver.rb +103 -113
  23. data/lib/net/dns/resolver/socks.rb +45 -51
  24. data/lib/net/dns/resolver/timeouts.rb +17 -26
  25. data/lib/net/dns/rr.rb +107 -117
  26. data/lib/net/dns/rr/a.rb +46 -55
  27. data/lib/net/dns/rr/aaaa.rb +40 -49
  28. data/lib/net/dns/rr/classes.rb +26 -29
  29. data/lib/net/dns/rr/cname.rb +33 -41
  30. data/lib/net/dns/rr/hinfo.rb +44 -56
  31. data/lib/net/dns/rr/mr.rb +33 -42
  32. data/lib/net/dns/rr/mx.rb +37 -47
  33. data/lib/net/dns/rr/ns.rb +33 -41
  34. data/lib/net/dns/rr/null.rb +8 -11
  35. data/lib/net/dns/rr/ptr.rb +14 -20
  36. data/lib/net/dns/rr/soa.rb +27 -30
  37. data/lib/net/dns/rr/srv.rb +13 -17
  38. data/lib/net/dns/rr/txt.rb +8 -11
  39. data/lib/net/dns/rr/types.rb +97 -99
  40. data/lib/net/dns/version.rb +5 -13
  41. data/net-dns.gemspec +17 -29
  42. data/{fixtures → spec/fixtures}/resolv.conf +0 -0
  43. data/spec/spec_helper.rb +14 -0
  44. data/spec/unit/resolver/dns_timeout_spec.rb +36 -0
  45. data/spec/unit/resolver/tcp_timeout_spec.rb +46 -0
  46. data/spec/unit/resolver/udp_timeout_spec.rb +46 -0
  47. data/test/test_helper.rb +12 -3
  48. data/test/{header_test.rb → unit/header_test.rb} +43 -46
  49. data/test/{names_test.rb → unit/names_test.rb} +1 -1
  50. data/test/{packet_test.rb → unit/packet_test.rb} +3 -5
  51. data/test/{question_test.rb → unit/question_test.rb} +3 -5
  52. data/test/{resolver_test.rb → unit/resolver_test.rb} +10 -13
  53. data/test/{rr → unit/rr}/a_test.rb +10 -17
  54. data/test/{rr → unit/rr}/aaaa_test.rb +7 -14
  55. data/test/{rr → unit/rr}/classes_test.rb +14 -16
  56. data/test/{rr → unit/rr}/cname_test.rb +7 -14
  57. data/test/{rr → unit/rr}/hinfo_test.rb +16 -22
  58. data/test/{rr → unit/rr}/mr_test.rb +12 -18
  59. data/test/{rr → unit/rr}/mx_test.rb +18 -24
  60. data/test/{rr → unit/rr}/ns_test.rb +10 -16
  61. data/test/{rr → unit/rr}/types_test.rb +10 -8
  62. data/test/{rr_test.rb → unit/rr_test.rb} +33 -37
  63. metadata +77 -49
  64. data/test/resolver/timeouts_test.rb +0 -109
@@ -2,18 +2,16 @@ require 'socket'
2
2
  require 'ipaddr'
3
3
 
4
4
  class RawSocket # :nodoc:
5
-
6
5
  @@id_arr = []
7
-
8
- def initialize(src_addr,dest_addr)
9
-
6
+
7
+ def initialize(src_addr, dest_addr)
10
8
  # Define socket
11
9
  begin
12
10
  @socket = Socket.new PF_INET, SOCK_RAW, IPPROTO_RAW
13
11
  rescue SystemCallError => e
14
12
  raise SystemCallError, "You must be root to use raw sockets! #{e}"
15
13
  end
16
-
14
+
17
15
  @socket.setsockopt IPPROTO_IP, IP_HDRINCL, 1
18
16
 
19
17
  # Checks addresses
@@ -26,7 +24,7 @@ class RawSocket # :nodoc:
26
24
 
27
25
  # Set correct protocol version in the header
28
26
  @version = @dest_addr.ipv4? ? "0100" : "0110"
29
-
27
+
30
28
  # Total lenght: must be overridden by subclasses
31
29
  @tot_lenght = 20
32
30
 
@@ -38,49 +36,50 @@ class RawSocket # :nodoc:
38
36
  @id = 1234
39
37
 
40
38
  # Generate peer sockaddr
41
- @to = Socket.pack_sockaddr_in @dest_port, @dest_addr.to_s
39
+ @to = Socket.pack_sockaddr_in @dest_port, @dest_addr.to_s
42
40
  end
43
41
 
44
42
  def send(payload = '')
45
- packet = make_ip_header([[ @version+'0101', 'B8' ], # version, hlen
46
- [ 0, 'C' ], # tos
47
- [ @tot_lenght + payload.size, 'n' ], # total len
48
- [ @id, 'n' ], # id
49
- [ 0, 'n' ], # flags, offset
50
- [ 64, 'C' ], # ttl
51
- [ @protocol, 'C' ], # protocol
52
- [ 0, 'n' ], # checksum
53
- [ @src_addr.to_i, 'N' ], # source
54
- [ @dest_addr.to_i, 'N' ], # destination
55
- ])
43
+ packet = make_ip_header([
44
+ [@version + '0101', 'B8'], # version, hlen
45
+ [0, 'C'], # tos
46
+ [@tot_lenght + payload.size, 'n'], # total len
47
+ [@id, 'n'], # id
48
+ [0, 'n'], # flags, offset
49
+ [64, 'C'], # ttl
50
+ [@protocol, 'C'], # protocol
51
+ [0, 'n'], # checksum
52
+ [@src_addr.to_i, 'N'], # source
53
+ [@dest_addr.to_i, 'N'], # destination
54
+ ])
56
55
  packet << make_transport_header(payload.size)
57
56
  packet << [payload].pack("a*")
58
- @socket.send(packet,0,@to)
59
- end
57
+ @socket.send(packet, 0, @to)
58
+ end
60
59
 
61
60
  private
62
-
63
- def check_addr addr
61
+
62
+ def check_addr(addr)
64
63
  case addr
65
- when String
66
- IPAddr.new(addr)
67
- when IPAddr
68
- addr
69
- else
70
- raise ArgumentError, "Wrong address format: #{addr}"
64
+ when String
65
+ IPAddr.new(addr)
66
+ when IPAddr
67
+ addr
68
+ else
69
+ raise ArgumentError, "Wrong address format: #{addr}"
71
70
  end
72
71
  end
73
-
74
- def check_port port
75
- if (1..65535).include? port and port.kind_of? Integer
72
+
73
+ def check_port(port)
74
+ if (1..65_535).cover?(port) && port.is_a?(Integer)
76
75
  port
77
76
  else
78
77
  raise ArgumentError, "Port #{port} not valid"
79
78
  end
80
79
  end
81
-
80
+
82
81
  def genID
83
- while (@@id_arr.include?(q = rand(65535)))
82
+ while @@id_arr.include?(q = rand(65_535))
84
83
  end
85
84
  @@id_arr.push(q)
86
85
  q
@@ -103,34 +102,31 @@ class RawSocket # :nodoc:
103
102
  data[-3] = checksum
104
103
  data.pack(template)
105
104
  end
106
-
105
+
107
106
  def make_transport_header
108
107
  ""
109
108
  end
110
-
111
109
  end
112
110
 
113
111
  class UdpRawSocket < RawSocket # :nodoc:
112
+ def initialize(src_addr, src_port, dest_addr, dest_port)
113
+ super(src_addr, dest_addr)
114
114
 
115
- def initialize(src_addr,src_port,dest_addr,dest_port)
116
-
117
- super(src_addr,dest_addr)
118
-
119
115
  # Check ports
120
116
  @src_port = check_port src_port
121
117
  @dest_port = check_port dest_port
122
-
118
+
123
119
  # Total lenght: must be overridden by subclasses
124
120
  @tot_lenght = 20 + 8 # 8 bytes => UDP Header
125
121
 
126
122
  # Protocol: must be overridden by subclasses
127
123
  @protocol = 17 # UDP protocol
128
124
 
129
- @to = Socket.pack_sockaddr_in @dest_port, @dest_addr.to_s
125
+ @to = Socket.pack_sockaddr_in @dest_port, @dest_addr.to_s
130
126
  end
131
127
 
132
128
  private
133
-
129
+
134
130
  def make_udp_header(parts)
135
131
  template = ''
136
132
  data = []
@@ -139,16 +135,14 @@ class UdpRawSocket < RawSocket # :nodoc:
139
135
  template << part[-1]
140
136
  end
141
137
  data.pack(template)
142
- end
143
-
138
+ end
139
+
144
140
  def make_transport_header(pay_size)
145
141
  make_udp_header([
146
- [ @src_port, 'n'], # source port
147
- [ @dest_port, 'n' ], # destination port
148
- [ 8 + pay_size, 'n' ], # len
149
- [ 0, 'n' ] # checksum (mandatory)
150
- ])
142
+ [@src_port, 'n'], # source port
143
+ [@dest_port, 'n'], # destination port
144
+ [8 + pay_size, 'n'], # len
145
+ [0, 'n'] # checksum (mandatory)
146
+ ])
151
147
  end
152
-
153
148
  end
154
-
@@ -3,14 +3,11 @@ require 'timeout'
3
3
  module Net # :nodoc:
4
4
  module DNS
5
5
  class Resolver
6
-
7
6
  class DnsTimeout
8
-
9
7
  attr_reader :seconds
10
8
 
11
-
12
9
  def initialize(seconds)
13
- if seconds.is_a? Numeric and seconds >= 0
10
+ if seconds.is_a?(Numeric) && seconds >= 0
14
11
  @seconds = seconds
15
12
  else
16
13
  raise ArgumentError, "Invalid value for tcp timeout"
@@ -20,11 +17,7 @@ module Net # :nodoc:
20
17
  # Returns a string representation of the timeout corresponding
21
18
  # to the number of <tt>@seconds</tt>.
22
19
  def to_s
23
- if @seconds == 0
24
- @output.to_s
25
- else
26
- @seconds.to_s
27
- end
20
+ @seconds == 0 ? @output.to_s : @seconds.to_s
28
21
  end
29
22
 
30
23
  def pretty_to_s
@@ -37,27 +30,26 @@ module Net # :nodoc:
37
30
  # If @seconds is 0 or nil, no timeout is set.
38
31
  def timeout(&block)
39
32
  raise LocalJumpError, "no block given" unless block_given?
33
+
40
34
  Timeout.timeout(@seconds, &block)
41
35
  end
42
36
 
43
-
44
37
  private
45
38
 
46
- def transform(secs)
47
- case secs
48
- when 0
49
- to_s
50
- when 1..59
51
- "#{secs} seconds"
52
- when 60..3559
53
- "#{secs / 60} minutes and #{secs % 60} seconds"
54
- else
55
- hours = secs / 3600
56
- secs -= (hours * 3600)
57
- "#{hours} hours, #{secs / 60} minutes and #{secs % 60} seconds"
58
- end
39
+ def transform(secs)
40
+ case secs
41
+ when 0
42
+ to_s
43
+ when 1..59
44
+ "#{secs} seconds"
45
+ when 60..3559
46
+ "#{secs / 60} minutes and #{secs % 60} seconds"
47
+ else
48
+ hours = secs / 3600
49
+ secs -= (hours * 3600)
50
+ "#{hours} hours, #{secs / 60} minutes and #{secs % 60} seconds"
59
51
  end
60
-
52
+ end
61
53
  end
62
54
 
63
55
  class TcpTimeout < DnsTimeout
@@ -73,7 +65,6 @@ module Net # :nodoc:
73
65
  super
74
66
  end
75
67
  end
76
-
77
68
  end
78
69
  end
79
- end
70
+ end
@@ -1,15 +1,14 @@
1
1
  require 'ipaddr'
2
- require 'net/dns/names'
3
- require 'net/dns/rr/types'
4
- require 'net/dns/rr/classes'
2
+ require_relative 'names'
3
+ require_relative 'rr/types'
4
+ require_relative 'rr/classes'
5
5
 
6
- %w(a aaaa cname hinfo mr mx ns ptr soa srv txt).each do |file|
7
- require "net/dns/rr/#{file}"
6
+ %w[a aaaa cname hinfo mr mx ns ptr soa srv txt].each do |file|
7
+ require_relative "rr/#{file}"
8
8
  end
9
9
 
10
10
  module Net
11
11
  module DNS
12
-
13
12
  #
14
13
  # = Net::DNS::RR - DNS Resource Record class
15
14
  #
@@ -42,7 +41,6 @@ module Net
42
41
  class RR
43
42
  include Names
44
43
 
45
-
46
44
  # Base error class.
47
45
  class Error < StandardError
48
46
  end
@@ -51,7 +49,6 @@ module Net
51
49
  class DataError < Error
52
50
  end
53
51
 
54
-
55
52
  # Regexp matching an RR string
56
53
  RR_REGEXP = Regexp.new("^\\s*(\\S+)\\s*(\\d+)?\\s+(" +
57
54
  Net::DNS::RR::Classes.regexp +
@@ -63,7 +60,6 @@ module Net
63
60
  # RR portion of the packet, in bytes
64
61
  RRFIXEDSZ = 10
65
62
 
66
-
67
63
  # Create a new instance of Net::DNS::RR class, or an instance of
68
64
  # any of the subclass of the appropriate type.
69
65
  #
@@ -108,12 +104,12 @@ module Net
108
104
  #
109
105
  def initialize(arg)
110
106
  instance = case arg
111
- when String
112
- new_from_string(arg)
113
- when Hash
114
- new_from_hash(arg)
115
- else
116
- raise ArgumentError, "Invalid argument, must be a RR string or an hash of values"
107
+ when String
108
+ new_from_string(arg)
109
+ when Hash
110
+ new_from_hash(arg)
111
+ else
112
+ raise ArgumentError, "Invalid argument, must be a RR string or an hash of values"
117
113
  end
118
114
 
119
115
  if @type.to_s == "ANY"
@@ -133,7 +129,7 @@ module Net
133
129
  # This method is used when parsing a binary packet by the Packet
134
130
  # class.
135
131
  #
136
- def RR.parse(data)
132
+ def self.parse(data)
137
133
  o = allocate
138
134
  obj, offset = o.send(:new_from_binary, data, 0)
139
135
  obj
@@ -146,18 +142,14 @@ module Net
146
142
  # Return an instance of appropriate class and the offset
147
143
  # pointing at the end of the data parsed.
148
144
  #
149
- def RR.parse_packet(data, offset)
145
+ def self.parse_packet(data, offset)
150
146
  o = allocate
151
147
  o.send(:new_from_binary, data, offset)
152
148
  end
153
149
 
154
- def name
155
- @name
156
- end
150
+ attr_reader :name
157
151
 
158
- def ttl
159
- @ttl
160
- end
152
+ attr_reader :ttl
161
153
 
162
154
  # Type accessor
163
155
  def type
@@ -169,16 +161,13 @@ module Net
169
161
  @cls.to_s
170
162
  end
171
163
 
172
-
173
164
  def value
174
165
  get_inspect
175
166
  end
176
167
 
177
168
  # Data belonging to that appropriate class,
178
169
  # not to be used (use real accessors instead)
179
- def rdata
180
- @rdata
181
- end
170
+ attr_reader :rdata
182
171
 
183
172
  # Return the RR object in binary data format, suitable
184
173
  # for using in network streams.
@@ -201,14 +190,13 @@ module Net
201
190
  #
202
191
  # TO FIX in one of the future releases
203
192
  #
204
- def comp_data(offset,compnames)
193
+ def comp_data(offset, compnames)
205
194
  str, offset, names = dn_comp(@name, offset, compnames)
206
195
  str += [@type.to_i, @cls.to_i, ttl, @rdlength].pack("n2 N n")
207
196
  offset += Net::DNS::RRFIXEDSZ
208
197
  [str, offset, names]
209
198
  end
210
199
 
211
-
212
200
  # Returns a human readable representation of this record.
213
201
  # The value is always a String.
214
202
  #
@@ -226,7 +214,7 @@ module Net
226
214
  # #=> "example.com. 7200 IN MX 10 mailhost.example.com."
227
215
  #
228
216
  def to_s
229
- items = to_a.map { |e| e.to_s }
217
+ items = to_a.map(&:to_s)
230
218
  if @name.size < 24
231
219
  items.pack("A24 A8 A8 A8 A*")
232
220
  else
@@ -244,123 +232,125 @@ module Net
244
232
  [name, ttl, cls.to_s, type.to_s, value]
245
233
  end
246
234
 
247
-
248
235
  private
249
236
 
250
- def new_from_string(rrstring)
251
- unless rrstring =~ RR_REGEXP
252
- raise ArgumentError,
253
- "Format error for RR string (maybe CLASS and TYPE not valid?)"
254
- end
237
+ def new_from_string(rrstring)
238
+ unless rrstring =~ RR_REGEXP
239
+ raise ArgumentError,
240
+ "Format error for RR string (maybe CLASS and TYPE not valid?)"
241
+ end
255
242
 
256
- # Name of RR - mandatory
257
- begin
258
- @name = $1.downcase
259
- rescue NoMethodError
260
- raise ArgumentError, "Missing name field in RR string #{rrstring}"
261
- end
243
+ # Name of RR - mandatory
244
+ begin
245
+ @name = Regexp.last_match(1).downcase
246
+ rescue NoMethodError
247
+ raise ArgumentError, "Missing name field in RR string #{rrstring}"
248
+ end
262
249
 
263
- # Time to live for RR, default 3 hours
264
- @ttl = $2 ? $2.to_i : 10800
250
+ # Time to live for RR, default 3 hours
251
+ @ttl = Regexp.last_match(2) ? Regexp.last_match(2).to_i : 10_800
265
252
 
266
- # RR class, default to IN
267
- @cls = Net::DNS::RR::Classes.new $3
253
+ # RR class, default to IN
254
+ @cls = Net::DNS::RR::Classes.new Regexp.last_match(3)
268
255
 
269
- # RR type, default to A
270
- @type = Net::DNS::RR::Types.new $4
256
+ # RR type, default to A
257
+ @type = Net::DNS::RR::Types.new Regexp.last_match(4)
271
258
 
272
- # All the rest is data
273
- @rdata = $5 ? $5.strip : ""
259
+ # All the rest is data
260
+ @rdata = Regexp.last_match(5) ? Regexp.last_match(5).strip : ""
274
261
 
275
- if self.class == Net::DNS::RR
276
- Net::DNS::RR.const_get(@type.to_s).new(rrstring)
277
- else
278
- subclass_new_from_string(@rdata)
279
- self.class
280
- end
262
+ if self.class == Net::DNS::RR
263
+ Net::DNS::RR.const_get(@type.to_s).new(rrstring)
264
+ else
265
+ subclass_new_from_string(@rdata)
266
+ self.class
281
267
  end
268
+ end
282
269
 
283
- def new_from_hash(args)
284
- # Name field is mandatory
285
- unless args.has_key? :name
286
- raise ArgumentError, ":name field is mandatory"
287
- end
270
+ def new_from_hash(args)
271
+ # Name field is mandatory
272
+ unless args.key? :name
273
+ raise ArgumentError, ":name field is mandatory"
274
+ end
288
275
 
289
- @name = args[:name].downcase
290
- @ttl = args[:ttl] ? args[:ttl].to_i : 10800 # Default 3 hours
291
- @type = Net::DNS::RR::Types.new args[:type]
292
- @cls = Net::DNS::RR::Classes.new args[:cls]
276
+ @name = args[:name].downcase
277
+ @ttl = args[:ttl] ? args[:ttl].to_i : 10_800 # Default 3 hours
278
+ @type = Net::DNS::RR::Types.new args[:type]
279
+ @cls = Net::DNS::RR::Classes.new args[:cls]
293
280
 
294
- @rdata = args[:rdata] ? args[:rdata].strip : ""
295
- @rdlength = args[:rdlength] || @rdata.size
281
+ @rdata = args[:rdata] ? args[:rdata].strip : ""
282
+ @rdlength = args[:rdlength] || @rdata.size
296
283
 
297
- if self.class == Net::DNS::RR
298
- Net::DNS::RR.const_get(@type.to_s).new(args)
284
+ if self.class == Net::DNS::RR
285
+ Net::DNS::RR.const_get(@type.to_s).new(args)
286
+ else
287
+ hash = args - %i[name ttl type cls]
288
+ if hash.key? :rdata
289
+ subclass_new_from_string(hash[:rdata])
299
290
  else
300
- hash = args - [:name, :ttl, :type, :cls]
301
- if hash.has_key? :rdata
302
- subclass_new_from_string(hash[:rdata])
303
- else
304
- subclass_new_from_hash(hash)
305
- end
306
- self.class
291
+ subclass_new_from_hash(hash)
307
292
  end
293
+ self.class
308
294
  end
295
+ end
309
296
 
310
- def new_from_binary(data,offset)
311
- if self.class == Net::DNS::RR
312
- temp = dn_expand(data,offset)[1]
313
- type = Net::DNS::RR::Types.new data.unpack("@#{temp} n")[0]
314
- (eval "Net::DNS::RR::#{type}").parse_packet(data,offset)
315
- else
316
- @name,offset = dn_expand(data,offset)
317
- rrtype,cls,@ttl,@rdlength = data.unpack("@#{offset} n2 N n")
318
- @type = Net::DNS::RR::Types.new rrtype
319
- @cls = Net::DNS::RR::Classes.new cls
320
- offset += RRFIXEDSZ
321
- offset = subclass_new_from_binary(data,offset)
322
- build_pack
323
- set_type
324
- [self, offset]
325
- end
297
+ def new_from_binary(data, offset)
298
+ if self.class == Net::DNS::RR
299
+ temp = dn_expand(data, offset)[1]
300
+ type = Net::DNS::RR::Types.new data.unpack("@#{temp} n")[0]
301
+ (eval "Net::DNS::RR::#{type}").parse_packet(data, offset)
302
+ else
303
+ @name, offset = dn_expand(data, offset)
304
+ rrtype, cls, @ttl, @rdlength = data.unpack("@#{offset} n2 N n")
305
+ @type = Net::DNS::RR::Types.new rrtype
306
+ @cls = Net::DNS::RR::Classes.new cls
307
+ offset += RRFIXEDSZ
308
+ offset = subclass_new_from_binary(data, offset)
309
+ build_pack
310
+ set_type
311
+ [self, offset]
326
312
  end
313
+ end
327
314
 
328
- # Methods to be overridden by subclasses
329
- def subclass_new_from_array(arr)
330
- end
331
- def subclass_new_from_string(str)
332
- end
333
- def subclass_new_from_hash(hash)
334
- end
335
- def subclass_new_from_binary(data, offset)
336
- end
337
- def build_pack
338
- end
339
- def get_inspect
340
- @rdata
341
- end
342
- def get_data
343
- @rdata
344
- end
315
+ # Methods to be overridden by subclasses
316
+ def subclass_new_from_array(arr)
317
+ end
345
318
 
346
- def set_type
347
- # TODO: Here we should probably
348
- # raise NotImplementedError
349
- # if we want the method to be implemented in any subclass.
350
- end
319
+ def subclass_new_from_string(str)
320
+ end
351
321
 
322
+ def subclass_new_from_hash(hash)
323
+ end
324
+
325
+ def subclass_new_from_binary(data, offset)
326
+ end
327
+
328
+ def build_pack
329
+ end
330
+
331
+ def get_inspect
332
+ @rdata
333
+ end
334
+
335
+ def get_data
336
+ @rdata
337
+ end
338
+
339
+ def set_type
340
+ # TODO: Here we should probably
341
+ # raise NotImplementedError
342
+ # if we want the method to be implemented in any subclass.
343
+ end
352
344
 
353
345
  def self.new(*args)
354
346
  o = allocate
355
- obj = o.send(:initialize,*args)
347
+ obj = o.send(:initialize, *args)
356
348
  if self == Net::DNS::RR
357
349
  obj
358
350
  else
359
351
  o
360
352
  end
361
353
  end
362
-
363
354
  end
364
-
365
355
  end
366
356
  end