dnsruby 1.46 → 1.47

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.
@@ -65,6 +65,11 @@ module Dnsruby
65
65
  #
66
66
  # Defaults to false
67
67
  attr_accessor :use_tcp
68
+
69
+ # Use UDP only - don't use TCP
70
+ # For test/debug purposes only
71
+ # Defaults to false
72
+ attr_accessor :no_tcp
68
73
 
69
74
  # The TSIG record to sign/verify messages with
70
75
  attr_reader :tsig
@@ -152,6 +157,7 @@ module Dnsruby
152
157
  # * :server
153
158
  # * :port
154
159
  # * :use_tcp
160
+ # * :no_tcp
155
161
  # * :ignore_truncation
156
162
  # * :src_address
157
163
  # * :src_port
@@ -166,6 +172,7 @@ module Dnsruby
166
172
  @udp_size = Resolver::DefaultUDPSize
167
173
  @dnssec = Resolver::DefaultDnssec
168
174
  @use_tcp = false
175
+ @no_tcp = false
169
176
  @tsig = nil
170
177
  @ignore_truncation = false
171
178
  @src_address = '0.0.0.0'
@@ -312,6 +319,13 @@ module Dnsruby
312
319
  end
313
320
  # Otherwise, run the query
314
321
  if (udp_packet_size < query_packet.length)
322
+ if (@no_tcp)
323
+ # Can't send the message - abort!
324
+ err=IOError.new("Can't send message - too big for UDP and no_tcp=true")
325
+ Dnsruby.log.error{"#{err}"}
326
+ st.push_exception_to_select(client_query_id, client_queue, err, nil)
327
+ return
328
+ end
315
329
  Dnsruby.log.debug{"Query packet length exceeds max UDP packet size - using TCP"}
316
330
  use_tcp = true
317
331
  end
@@ -392,10 +406,10 @@ module Dnsruby
392
406
  end
393
407
  socket.send(query_bytes, 0)
394
408
  rescue Exception => e
395
- st.push_exception_to_select(client_query_id, client_queue, err, nil)
396
- socket.close
397
409
  err=IOError.new("Send failed to #{@server}:#{@port} from #{@src_address}:#{src_port}, use_tcp=#{use_tcp}, exception : #{e}")
398
410
  Dnsruby.log.error{"#{err}"}
411
+ st.push_exception_to_select(client_query_id, client_queue, err, nil)
412
+ socket.close
399
413
  return
400
414
  end
401
415
 
@@ -499,12 +513,16 @@ module Dnsruby
499
513
  end
500
514
  end
501
515
  if (response.header.tc && !tcp && !@ignore_truncation)
502
- # Try to resend over tcp
503
- Dnsruby.log.debug{"Truncated - resending over TCP"}
504
- # @TODO@ Are the query options used correctly here? DNSSEC in particular...
505
- # query.send_raw = true # Make sure that the packet is not messed with.
506
- send_async(query, client_queue, client_query_id, true)
507
- return false
516
+ if (@no_tcp)
517
+ Dnsruby.log.debug{"Truncated response - not resending over TCP as no_tcp==true"}
518
+ else
519
+ # Try to resend over tcp
520
+ Dnsruby.log.debug{"Truncated - resending over TCP"}
521
+ # @TODO@ Are the query options used correctly here? DNSSEC in particular...
522
+ # query.send_raw = true # Make sure that the packet is not messed with.
523
+ send_async(query, client_queue, client_query_id, true)
524
+ return false
525
+ end
508
526
  end
509
527
  return true
510
528
  end
@@ -549,12 +567,12 @@ module Dnsruby
549
567
  packet.header.rd=@recurse
550
568
  end
551
569
 
552
- # @TODO@ Only do this if the packet has not been prepared already!
570
+ # Only do this if the packet has not been prepared already!
553
571
  if (@dnssec)
554
572
  prepare_for_dnssec(packet)
555
-
556
573
  elsif ((udp_packet_size > Resolver::DefaultUDPSize) && !use_tcp)
557
574
  # if ((udp_packet_size > Resolver::DefaultUDPSize) && !use_tcp)
575
+ # @TODO@ What if an existing OPT RR is not big enough? Should we replace it?
558
576
  add_opt_rr(packet)
559
577
  end
560
578
  end
@@ -570,7 +588,10 @@ module Dnsruby
570
588
  # RFC 3225
571
589
  optrr = RR::OPT.new(udp_packet_size)
572
590
 
573
- packet.add_additional(optrr)
591
+ # Only one OPT RR allowed per packet - do we already have one?
592
+ if (packet.additional.rrset(packet.question()[0].qname, Types::OPT).rrs.length == 0)
593
+ packet.add_additional(optrr)
594
+ end
574
595
  end
575
596
 
576
597
  def prepare_for_dnssec(packet)
@@ -78,7 +78,12 @@ module Dnsruby
78
78
  attr_reader :port
79
79
 
80
80
  # Should TCP be used as a transport rather than UDP?
81
+ # If use_tcp==true, then ONLY TCP will be used as a transport.
81
82
  attr_reader :use_tcp
83
+
84
+ # If no_tcp==true, then ONLY UDP will be used as a transport.
85
+ # This should not generally be used, but is provided as a debugging aid.
86
+ attr_reader :no_tcp
82
87
 
83
88
 
84
89
  attr_reader :tsig
@@ -288,7 +293,7 @@ module Dnsruby
288
293
  #* msg - the message to send
289
294
  #* client_queue - a Queue to push the response to, when it arrives
290
295
  #* client_query_id - an optional ID to identify the query to the client
291
- #* use_tcp - whether to use TCP (defaults to SingleResolver.use_tcp)
296
+ #* use_tcp - whether to use only TCP (defaults to SingleResolver.use_tcp)
292
297
  #
293
298
  #Returns :
294
299
  #
@@ -417,12 +422,13 @@ module Dnsruby
417
422
  @single_res_mutex.synchronize {
418
423
  # Add the Config nameservers
419
424
  @config.nameserver.each do |ns|
420
- @single_resolvers.push(PacketSender.new({:server=>ns, :dnssec=>@dnssec,
421
- :use_tcp=>@use_tcp, :packet_timeout=>@packet_timeout,
425
+ res = PacketSender.new({:server=>ns, :dnssec=>@dnssec,
426
+ :use_tcp=>@use_tcp, :no_tcp=>@no_tcp, :packet_timeout=>@packet_timeout,
422
427
  :tsig => @tsig, :ignore_truncation=>@ignore_truncation,
423
428
  :src_address=>@src_address, :src_port=>@src_port,
424
429
  :do_caching=>@do_caching,
425
- :recurse=>@recurse, :udp_size=>@udp_size}))
430
+ :recurse=>@recurse, :udp_size=>@udp_size})
431
+ @single_resolvers.push(res) if res
426
432
  end
427
433
  }
428
434
  end
@@ -457,6 +463,7 @@ module Dnsruby
457
463
  @dnssec = DefaultDnssec
458
464
  @do_caching= true
459
465
  @use_tcp = false
466
+ @no_tcp = false
460
467
  @tsig = nil
461
468
  @ignore_truncation = false
462
469
  @config = Config.new()
@@ -472,6 +479,7 @@ module Dnsruby
472
479
  def update #:nodoc: all
473
480
  #Update any resolvers we have with the latest config
474
481
  @single_res_mutex.synchronize {
482
+ @single_resolvers.delete(nil) # Just in case...
475
483
  @single_resolvers.each do |res|
476
484
  update_internal_res(res)
477
485
  end
@@ -488,6 +496,7 @@ module Dnsruby
488
496
  def add_server(server)# :nodoc:
489
497
  @configured = true
490
498
  res = PacketSender.new(server)
499
+ raise ArgumentError.new("Can't create server #{server}") if !res
491
500
  update_internal_res(res)
492
501
  @single_res_mutex.synchronize {
493
502
  @single_resolvers.push(res)
@@ -495,7 +504,7 @@ module Dnsruby
495
504
  end
496
505
 
497
506
  def update_internal_res(res)
498
- [:port, :use_tcp, :tsig, :ignore_truncation, :packet_timeout,
507
+ [:port, :use_tcp, :no_tcp, :tsig, :ignore_truncation, :packet_timeout,
499
508
  :src_address, :src_port, :recurse,
500
509
  :udp_size, :dnssec].each do |param|
501
510
 
@@ -625,6 +634,11 @@ module Dnsruby
625
634
  @use_tcp = on
626
635
  update
627
636
  end
637
+
638
+ def no_tcp=(on)
639
+ @no_tcp=on
640
+ update
641
+ end
628
642
 
629
643
  #Sets the TSIG to sign outgoing messages with.
630
644
  #Pass in either a Dnsruby::RR::TSIG, or a key_name and key (or just a key)
@@ -732,11 +746,10 @@ module Dnsruby
732
746
  if (retry_count>0)
733
747
  retry_delay *= 2
734
748
  end
735
- # servers=[]
736
- # @single_resolvers.each do |r| servers.push(r.server) end
749
+
750
+ @single_resolvers.delete(nil) # Just in case...
737
751
  @single_resolvers.each_index do |i|
738
752
  res= @single_resolvers[i]
739
- next if !res # @TODO@ WHY?1
740
753
  offset = (i*@retry_delay.to_f/@single_resolvers.length)
741
754
  if (retry_count==0)
742
755
  timeouts[base+offset]=[res, retry_count]
@@ -43,6 +43,7 @@ module Dnsruby
43
43
  # * :server
44
44
  # * :port
45
45
  # * :use_tcp
46
+ # * :no_tcp
46
47
  # * :ignore_truncation
47
48
  # * :src_address
48
49
  # * :src_port
@@ -61,6 +62,7 @@ module Dnsruby
61
62
  @udp_size = Resolver::DefaultUDPSize
62
63
  @dnssec = Resolver::DefaultDnssec
63
64
  @use_tcp = false
65
+ @no_tcp = false
64
66
  @tsig = nil
65
67
  @ignore_truncation = false
66
68
  @src_address = nil
@@ -111,7 +113,7 @@ module Dnsruby
111
113
  end
112
114
 
113
115
  isr = PacketSender.new({:server=>@server, :dnssec=>@dnssec,
114
- :use_tcp=>@use_tcp, :packet_timeout=>@packet_timeout,
116
+ :use_tcp=>@use_tcp, :no_tcp=>@no_tcp, :packet_timeout=>@packet_timeout,
115
117
  :tsig => @tsig, :ignore_truncation=>@ignore_truncation,
116
118
  :src_address=>@src_address, :src_port=>@src_port,
117
119
  :do_caching=>@do_caching,
@@ -128,7 +130,7 @@ module Dnsruby
128
130
  end
129
131
  @server = Config.resolve_server(s).to_s
130
132
  isr = PacketSender.new({:server=>@server, :dnssec=>@dnssec,
131
- :use_tcp=>@use_tcp, :packet_timeout=>@packet_timeout,
133
+ :use_tcp=>@use_tcp, :no_tcp=>@no_tcp, :packet_timeout=>@packet_timeout,
132
134
  :tsig => @tsig, :ignore_truncation=>@ignore_truncation,
133
135
  :src_address=>@src_address, :src_port=>@src_port,
134
136
  :do_caching=>@do_caching,
@@ -99,7 +99,10 @@ module Dnsruby
99
99
  if (rr.type == Types::RRSIG)
100
100
  type_ok = (rr.type_covered == type)
101
101
  end
102
- type_ok && (rr.klass == klass) && (rr.name.to_s.downcase == name.to_s.downcase)
102
+ if (!(/\.\z/ =~ name.to_s))
103
+ name = name.to_s + "."
104
+ end
105
+ type_ok && (rr.klass == klass) && (rr.name.to_s(true).downcase == name.to_s().downcase)
103
106
  }
104
107
  rrset = RRSet.new()
105
108
  rrs.each do |rr|
@@ -668,10 +671,7 @@ module Dnsruby
668
671
  attr_accessor :cd
669
672
 
670
673
  #The Authenticated Data flag
671
- attr_accessor :ad
672
-
673
674
  #Relevant in DNSSEC context.
674
- #
675
675
  #(The AD bit is only set on answers where signatures have been
676
676
  #cryptographically verified or the server is authoritative for the data
677
677
  #and is allowed to set the bit by policy.)
@@ -221,8 +221,12 @@ module Dnsruby
221
221
  # p Resolv::Name.create("x.y.z.").to_s #=> "x.y.z"
222
222
  # p Resolv::Name.create("x.y.z").to_s #=> "x.y.z"
223
223
  #
224
- def to_s
225
- return to_str(@labels)
224
+ def to_s(include_absolute=false)
225
+ ret = to_str(@labels)
226
+ if (@absolute && include_absolute)
227
+ ret += "."
228
+ end
229
+ return ret
226
230
  end
227
231
 
228
232
  def to_str(labels) # :nodoc: all
@@ -46,7 +46,7 @@ module Dnsruby
46
46
 
47
47
  def rdata_to_string #:nodoc: all
48
48
  if defined?@subtype
49
- return "#{@subtype} #{@hostname}."
49
+ return "#{@subtype} #{@hostname.to_s(true)}"
50
50
  else
51
51
  return '';
52
52
  end
@@ -105,7 +105,7 @@ module Dnsruby
105
105
  def rdata_to_string #:nodoc: all
106
106
  ret = "#{@pk_algorithm} #{hit_string} #{public_key_string}"
107
107
  @rsvs.each {|rsv|
108
- ret += " #{rsv}"
108
+ ret += " #{rsv.to_s(true)}"
109
109
  }
110
110
  return ret
111
111
  end
@@ -45,7 +45,7 @@ module Dnsruby
45
45
 
46
46
  def rdata_to_string #:nodoc: all
47
47
  if (@preference!=nil)
48
- return "#{@preference} #{@exchange}"
48
+ return "#{@preference} #{@exchange.to_s(true)}"
49
49
  else
50
50
  return ""
51
51
  end
@@ -49,7 +49,7 @@ module Dnsruby
49
49
 
50
50
  def rdata_to_string #:nodoc: all
51
51
  if (@rmailbx!=nil)
52
- return "#{@rmailbx} #{@emailbx}"
52
+ return "#{@rmailbx.to_s(true)} #{@emailbx.to_s(true)}"
53
53
  else
54
54
  return ""
55
55
  end
@@ -45,7 +45,7 @@ module Dnsruby
45
45
 
46
46
  def rdata_to_string #:nodoc: all
47
47
  if (@preference!=nil)
48
- return "#{@preference} #{@exchange}"
48
+ return "#{@preference} #{@exchange.to_s(true)}"
49
49
  else
50
50
  return ""
51
51
  end
@@ -67,7 +67,7 @@ module Dnsruby
67
67
  if (@order!=nil)
68
68
  ret = "#{@order} #{@preference} \"#{@flags}\" \"#{@service}\" \""
69
69
  ret += TXT.display(@regexp)
70
- ret += "\" #{@replacement}"
70
+ ret += "\" #{@replacement.to_s(true)}"
71
71
 
72
72
  return ret
73
73
  else
@@ -274,7 +274,7 @@ module Dnsruby
274
274
  type_strings.push(t.string)
275
275
  end
276
276
  types = type_strings.join(" ")
277
- return "#{@next_domain} ( #{types} )"
277
+ return "#{@next_domain.to_s(true)} ( #{types} )"
278
278
  else
279
279
  return ""
280
280
  end
@@ -47,7 +47,7 @@ module Dnsruby
47
47
 
48
48
  def rdata_to_string #:nodoc: all
49
49
  if (@preference!=nil)
50
- return "#{@preference} #{@map822} #{@mapx400}"
50
+ return "#{@preference} #{@map822.to_s(true)} #{@mapx400.to_s(true)}"
51
51
  else
52
52
  return ""
53
53
  end
@@ -46,7 +46,7 @@ module Dnsruby
46
46
 
47
47
  def rdata_to_string #:nodoc: all
48
48
  if (@mailbox!=nil)
49
- return "#{@mailbox} #{@txtdomain}"
49
+ return "#{@mailbox.to_s(true)} #{@txtdomain.to_s(true)}"
50
50
  else
51
51
  return ""
52
52
  end
@@ -232,7 +232,7 @@ module Dnsruby
232
232
  # @TODO@ Display the expiration and inception as
233
233
  return "#{@type_covered.string} #{@algorithm.string} #{@labels} #{@original_ttl} " +
234
234
  "#{format_time(@expiration)} ( #{format_time(@inception)} " +
235
- "#{@key_tag} #{@signers_name} #{signature} )"
235
+ "#{@key_tag} #{@signers_name.to_s(true)} #{signature} )"
236
236
  else
237
237
  return ""
238
238
  end
@@ -46,7 +46,7 @@ module Dnsruby
46
46
 
47
47
  def rdata_to_string #:nodoc: all
48
48
  if (@preference!=nil)
49
- return "#{@preference} #{@intermediate}"
49
+ return "#{@preference} #{@intermediate.to_s(true)}"
50
50
  else
51
51
  return ""
52
52
  end
@@ -71,7 +71,7 @@ module Dnsruby
71
71
 
72
72
  def rdata_to_string #:nodoc: all
73
73
  if (@mname!=nil)
74
- return "#{@mname} #{@rname} #{@serial} #{@refresh} #{@retry} #{@expire} #{@minimum}"
74
+ return "#{@mname.to_s(true)} #{@rname.to_s(true)} #{@serial} #{@refresh} #{@retry} #{@expire} #{@minimum}"
75
75
  else
76
76
  return ""
77
77
  end
@@ -86,7 +86,7 @@ module Dnsruby
86
86
 
87
87
  def rdata_to_string
88
88
  if (@target!=nil)
89
- return "#{@priority} #{@weight} #{@port} #{@target}"
89
+ return "#{@priority} #{@weight} #{@port} #{@target.to_s(true)}"
90
90
  else
91
91
  return ""
92
92
  end
@@ -131,7 +131,7 @@ module Dnsruby
131
131
  if (@algorithm!=nil)
132
132
  error = @error
133
133
  error = "UNDEFINED" unless error!=nil
134
- rdatastr = "#{@algorithm}. #{error}"
134
+ rdatastr = "#{@algorithm.to_s(true)} #{error}"
135
135
  if (@other_size != nil && @other_size >0 && @other_data!=nil)
136
136
  rdatastr += " #{@other_data}"
137
137
  end
@@ -550,7 +550,7 @@ module Dnsruby
550
550
  if (@algorithm!=nil)
551
551
  error = @error
552
552
  error = "UNDEFINED" unless error!=nil
553
- rdatastr = "#{@original_id} #{@time_signed} #{@algorithm}. #{error}";
553
+ rdatastr = "#{@original_id} #{@time_signed} #{@algorithm.to_s(true)} #{error}";
554
554
  if (@other_size > 0 && @other_data!=nil)
555
555
  rdatastr += " #{@other_data}"
556
556
  end
@@ -39,7 +39,7 @@ module Dnsruby
39
39
  end
40
40
 
41
41
  def rdata_to_string #:nodoc: all
42
- return @domainname.to_s
42
+ return @domainname.to_s(true)
43
43
  end
44
44
 
45
45
  def encode_rdata(msg, canonical=false) #:nodoc: all
@@ -503,7 +503,7 @@ module Dnsruby
503
503
 
504
504
  #Returns a string representation of the RR in zone file format
505
505
  def to_s
506
- return (@name ? @name.to_s():"") + ".\t" +(@ttl ? @ttl.to_s():"") + "\t" + (klass() ? klass.to_s():"") + "\t" + (type() ? type.to_s():"") + "\t" + rdata_to_string
506
+ return (@name ? @name.to_s(true):"") + "\t" +(@ttl ? @ttl.to_s():"") + "\t" + (klass() ? klass.to_s():"") + "\t" + (type() ? type.to_s():"") + "\t" + rdata_to_string
507
507
  end
508
508
 
509
509
  #Get a string representation of the data section of the RR (in zone file format)
@@ -58,6 +58,8 @@ module Dnsruby
58
58
  @@queued_responses=[]
59
59
  @@queued_validation_responses=[]
60
60
  @@wakeup_sockets = get_socket_pair
61
+ # Suppress reverse lookups
62
+ BasicSocket.do_not_reverse_lookup = true
61
63
  # end
62
64
  # Now start the select thread
63
65
  @@select_thread = Thread.new {
@@ -236,9 +238,16 @@ module Dnsruby
236
238
  answerip = msg.answerip.downcase
237
239
  answerfrom = msg.answerfrom.downcase
238
240
  dest_server = query_settings.dest_server
241
+ answeripaddr = IPAddr.new(answerip)
242
+ dest_server = IPAddr.new("0.0.0.0")
243
+ begin
244
+ destserveripaddr = IPAddr.new(dest_server)
245
+ rescue ArgumentError
246
+ # Host name not IP address
247
+ end
239
248
  if (dest_server && (dest_server != '0.0.0.0') &&
240
- (answerip != query_settings.dest_server.downcase) &&
241
- (answerfrom != query_settings.dest_server.downcase))
249
+ (answeripaddr != destserveripaddr) &&
250
+ (answerfrom != dest_server))
242
251
  Dnsruby.log.warn("Unsolicited response received from #{answerip} instead of #{query_settings.dest_server}")
243
252
  else
244
253
  send_response_to_client(msg, bytes, socket)
@@ -516,7 +525,11 @@ module Dnsruby
516
525
  # to send it out from its normal loop.
517
526
  Dnsruby.log.debug{"Pushing response to client queue direct from resolver or validator"}
518
527
  @@mutex.synchronize{
519
- @@queued_responses.push([client_id, client_queue, msg, nil, query, res])
528
+ err = nil
529
+ if (msg.rcode == RCode.NXDOMAIN)
530
+ err = NXDomain.new
531
+ end
532
+ @@queued_responses.push([client_id, client_queue, msg, err, query, res])
520
533
  }
521
534
  # Make sure select loop is running!
522
535
  if (@@select_thread && @@select_thread.alive?)
@@ -21,7 +21,7 @@ module Dnsruby
21
21
  class ValidatorThread # :nodoc: all
22
22
  # include Singleton
23
23
  def initialize(*args)
24
- @client_id, @client_queue, @response, @err, @query, @st, @res = args
24
+ @client_id, @client_queue, @response, @error, @query, @st, @res = args
25
25
  # Create the validation thread, and a queue to receive validation requests
26
26
  # Actually, need to have a thread per validator, as they make recursive calls.
27
27
  # @@mutex = Mutex.new
@@ -59,7 +59,7 @@ module Dnsruby
59
59
  # client_id, client_queue, response, err, query, st, res = item
60
60
  validated_ok = validate(@query, @response, @res)
61
61
 
62
- validated_ok = false if @error
62
+ validated_ok = false if (@error && !(NXDomain === @error))
63
63
 
64
64
  cache_if_valid(@query, @response)
65
65
 
@@ -332,8 +332,9 @@ module Dnsruby
332
332
  if ([Types::MX, Types::NS, Types::AFSDB, Types::NAPTR, Types::RT,
333
333
  Types::SRV, Types::CNAME, Types::MB, Types::MG, Types::MR,
334
334
  Types::PTR].include?type_was)
335
- if (line[line.length-1, 1] != ".")
336
- line = line + "." + @origin.to_s
335
+ # if (line[line.length-1, 1] != ".")
336
+ if (!(/\.\z/ =~ line))
337
+ line = line + "." + @origin.to_s + "."
337
338
  end
338
339
  end
339
340
  # Other RRs have several names. These should be parsed by Dnsruby,
@@ -104,7 +104,7 @@ require 'Dnsruby/TheLog'
104
104
  module Dnsruby
105
105
 
106
106
  # @TODO@ Remember to update version in dnsruby.gemspec!
107
- VERSION = 1.46
107
+ VERSION = 1.47
108
108
  def Dnsruby.version
109
109
  return VERSION
110
110
  end
@@ -22,7 +22,7 @@ require 'dnsruby'
22
22
  include Dnsruby
23
23
  class TestPacket < Test::Unit::TestCase
24
24
  def test_packet
25
- domain = "example.com"
25
+ domain = "example.com."
26
26
  type = "MX"
27
27
  klass = "IN"
28
28
 
@@ -48,43 +48,43 @@ class TestPacket < Test::Unit::TestCase
48
48
  assert(additional.length == 0, 'additional() works when empty'); #9
49
49
 
50
50
  packet.add_answer(RR.create( {
51
- :name => "a1.example.com",
51
+ :name => "a1.example.com.",
52
52
  :type => Types.A,
53
53
  :address => "10.0.0.1"}));
54
54
  assert_equal(1, packet.header.ancount, 'First push into answer section worked'); #10
55
55
 
56
56
 
57
- ret = packet.answer.rrset("example.com", 'NSEC')
57
+ ret = packet.answer.rrset("example.com.", 'NSEC')
58
58
  assert_equal(ret.rrs.length, 0, "#{ret.rrs.length}")
59
59
  ret = packet.answer.rrset("a1.example.com", 'A')
60
60
  assert_equal(ret.rrs.length, 1, "#{ret.rrs.length}")
61
61
  ret = packet.answer.rrsets()
62
62
  assert_equal(ret.length, 1, "#{ret.length}")
63
63
 
64
- packet.add_answer(RR.create({:name => "a2.example.com",
64
+ packet.add_answer(RR.create({:name => "a2.example.com.",
65
65
  :type => "A", :address => "10.0.0.2"}));
66
66
  assert_equal(packet.header.ancount, 2, 'Second push into answer section worked'); #11
67
67
 
68
- packet.add_authority(RR.create({:name => "a3.example.com",
68
+ packet.add_authority(RR.create({:name => "a3.example.com.",
69
69
  :type => "A",
70
70
  :address => "10.0.0.3"}));
71
71
  assert_equal(1, packet.header.nscount, 'First push into authority section worked'); #12
72
72
 
73
73
 
74
74
  packet.add_authority(RR.create( {
75
- :name => "a4.example.com",
75
+ :name => "a4.example.com.",
76
76
  :type => "A",
77
77
  :address => "10.0.0.4"}));
78
78
  assert_equal(2, packet.header.nscount, 'Second push into authority section worked'); #13
79
79
 
80
80
  packet.add_additional(RR.create({
81
- :name => "a5.example.com",
81
+ :name => "a5.example.com.",
82
82
  :type => "A",
83
83
  :address => "10.0.0.5"}));
84
84
  assert_equal(1, packet.header.adcount, 'First push into additional section worked'); #14
85
85
 
86
86
  packet.add_additional(RR.create( {
87
- :name => "a6.example.com",
87
+ :name => "a6.example.com.",
88
88
  :type => Types.A,
89
89
  :address => "10.0.0.6"}));
90
90
  assert_equal(2, packet.header.adcount, 'Second push into additional section worked'); #15
@@ -162,13 +162,13 @@ f4 00 31 04 64 6e 73 31 05 69 63 61 6e 6e 03 6f
162
162
  end
163
163
 
164
164
  def get_test_packet
165
- packet=Message.new("254.9.11.10.in-addr.arpa","PTR","IN")
165
+ packet=Message.new("254.9.11.10.in-addr.arpa.","PTR","IN")
166
166
 
167
- packet.add_answer(RR.create(%q[254.9.11.10.in-addr.arpa 86400 IN PTR host-84-11-9-254.customer.example.com]));
167
+ packet.add_answer(RR.create(%q[254.9.11.10.in-addr.arpa. 86400 IN PTR host-84-11-9-254.customer.example.com.]));
168
168
 
169
- packet.add_authority(RR.create("9.11.10.in-addr.arpa 86400 IN NS autons1.example.com"));
170
- packet.add_authority(RR.create("9.11.10.in-addr.arpa 86400 IN NS autons2.example.com"));
171
- packet.add_authority(RR.create("9.11.10.in-addr.arpa 86400 IN NS autons3.example.com"));
169
+ packet.add_authority(RR.create("9.11.10.in-addr.arpa. 86400 IN NS autons1.example.com."));
170
+ packet.add_authority(RR.create("9.11.10.in-addr.arpa. 86400 IN NS autons2.example.com."));
171
+ packet.add_authority(RR.create("9.11.10.in-addr.arpa. 86400 IN NS autons3.example.com."));
172
172
  return packet
173
173
  end
174
174
 
@@ -121,7 +121,7 @@ class TestResolver < Test::Unit::TestCase
121
121
  id, m, err = q.pop
122
122
  assert(id==1)
123
123
  assert(m.rcode == RCode.NXDOMAIN)
124
- assert(err.kind_of?(NXDomain))
124
+ assert(NXDomain === err)
125
125
  end
126
126
 
127
127
  def test_timeouts
@@ -66,9 +66,9 @@ class TestRrUnknown < Test::Unit::TestCase
66
66
 
67
67
 
68
68
  rr = RR.new_from_string('e.example IN TYPE4555 \# 4 0A0000 01 ')
69
- assert_equal('e.example. 0 IN TYPE4555 \# 4 0a000001', rr.to_s, 'Fully unknown RR parsed correctly')
69
+ assert_equal('e.example 0 IN TYPE4555 \# 4 0a000001', rr.to_s, 'Fully unknown RR parsed correctly')
70
70
 
71
- rr4 = RR.new_from_string('e.example CLASS122 TYPE4555 \# 4 0A0000 01 ')
71
+ rr4 = RR.new_from_string('e.example. CLASS122 TYPE4555 \# 4 0A0000 01 ')
72
72
  assert_equal('e.example. 0 CLASS122 TYPE4555 \# 4 0a000001', rr4.to_s, 'Fully unknown RR in unknown CLASS parsed correctly')
73
73
  end
74
74
 
@@ -14,11 +14,12 @@
14
14
  #limitations under the License.
15
15
  #++
16
16
  begin
17
- require 'rubygems'
17
+ require 'rubygems'
18
18
  rescue LoadError
19
19
  end
20
20
  require 'test/unit'
21
21
  require 'dnsruby'
22
+ require 'socket'
22
23
  class TestTcp < Test::Unit::TestCase
23
24
  def test_TCP
24
25
  res = Dnsruby::Resolver.new()
@@ -27,12 +28,54 @@ class TestTcp < Test::Unit::TestCase
27
28
  assert(ret.is_a?(Dnsruby::Message))
28
29
  end
29
30
  def test_TCP_port
30
- #@TODO@ Need a test server so we can tell what port this message was actually sent on!
31
+ # Need a test server so we can tell what port this message was actually sent on!
32
+ port = 59125
33
+ src_port = 57923
34
+ Dnsruby::PacketSender.clear_caches
35
+ received_port = nil
36
+ server_thread = Thread.new {
37
+ ts = TCPServer.new(port)
38
+ t = ts.accept
39
+ # Check that the source port was src_port
40
+ received_port = t.peeraddr()[1]
41
+ packet = t.recvfrom(2)[0]
42
+
43
+ len = (packet[0]<<8)+packet[1]
44
+ if (RUBY_VERSION >= "1.9")
45
+ len = (packet[0].getbyte(0)<<8)+packet[1].getbyte(0)# Ruby 1.9
46
+ end
47
+ packet = t.recvfrom(len)[0]
48
+ tcpPacket = Dnsruby::Message.decode(packet)
49
+ tcpPacket.header.tc = true
50
+ lenmsg = [tcpPacket.encode.length].pack('n')
51
+ t.send(lenmsg, 0)
52
+ t.write(tcpPacket.encode)
53
+ t.close
54
+ ts.close
55
+ }
56
+ ret = nil
57
+ client_thread = Thread.new {
58
+ res = Dnsruby::SingleResolver.new("127.0.0.1")
59
+ res.port = port
60
+ res.use_tcp = true
61
+ res.src_port=src_port
62
+ ret=res.query("example.com")
63
+ }
64
+ server_thread.join
65
+ client_thread.join
66
+ assert(received_port == src_port)
67
+ assert(ret.is_a?(Dnsruby::Message))
68
+ end
69
+
70
+ def test_no_tcp
71
+ # Try to get a long response (which is truncated) and check that we have
72
+ # tc bit set
31
73
  res = Dnsruby::Resolver.new()
32
- res.use_tcp = true
33
- res.src_port=60123
34
- ret=res.query("example.com")
35
- assert(ret.is_a?(Dnsruby::Message))
74
+ res.udp_size = 512
75
+ res.no_tcp = true
76
+ ret = res.query("overflow.dnsruby.validation-test-servers.nominet.org.uk", Dnsruby::Types.TXT)
77
+ assert(ret.header.tc, "Message should be truncated with no TCP")
36
78
  end
79
+
37
80
  #@TODO@ Check stuff like persistent sockets
38
81
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dnsruby
3
3
  version: !ruby/object:Gem::Version
4
- version: "1.46"
4
+ version: "1.47"
5
5
  platform: ruby
6
6
  authors:
7
7
  - AlexD
@@ -9,7 +9,7 @@ autorequire: dnsruby
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-04-07 00:00:00 +01:00
12
+ date: 2010-05-19 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15