Class: Resolv::DNS

Inherits:
Object
  • Object
show all
Defined in:
lib/net/dns/resolv.rb,
lib/net/dns/resolvx.rb,
lib/net/dns/resolvx.rb,
lib/net/dns/resolvx.rb,
lib/net/dns/resolvx.rb,
lib/net/dns/resolvx.rb

Defined Under Namespace

Modules: Label, OpCode, RCode Classes: Config, DecodeError, EncodeError, Message, Name, Query, Requester, Resource

Constant Summary collapse

Port =
53
UDPSize =
512
DNSThreadGroup =

:nodoc:

ThreadGroup.new

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_info = nil) ⇒ DNS

Returns a new instance of DNS.



428
429
430
431
432
# File 'lib/net/dns/resolv.rb', line 428

def initialize(config_info=nil)
  @mutex = Mutex.new
  @config = Config.new(config_info)
  @initialized = nil
end

Class Method Details

.open(*args) ⇒ Object



418
419
420
421
422
423
424
425
426
# File 'lib/net/dns/resolv.rb', line 418

def self.open(*args)
  dns = new(*args)
  return dns unless block_given?
  begin
    yield dns
  ensure
    dns.close
  end
end

Instance Method Details

#closeObject



451
452
453
454
455
456
457
458
459
# File 'lib/net/dns/resolv.rb', line 451

def close
  @mutex.synchronize {
    if @initialized
      @requester.close if @requester
      @requester = nil
      @initialized = false
    end
  }
end

#each_address(name) ⇒ Object



472
473
474
# File 'lib/net/dns/resolv.rb', line 472

def each_address(name)
  each_resource(name, Resource::IN::A) {|resource| yield resource.address}
end

#each_name(address) ⇒ Object



487
488
489
490
491
492
493
494
495
496
497
498
499
# File 'lib/net/dns/resolv.rb', line 487

def each_name(address)
  case address
  when Name
    ptr = address
  when IPv4::Regex
    ptr = IPv4.create(address).to_name
  when IPv6::Regex
    ptr = IPv6.create(address).to_name
  else
    raise ResolvError.new("cannot interpret as address: #{address}")
  end
  each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}
end

#each_resource(name, typeclass, &proc) ⇒ Object



512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
# File 'lib/net/dns/resolv.rb', line 512

def each_resource(name, typeclass, &proc)
  lazy_initialize
  q = Queue.new
  senders = {}
  begin
    @config.resolv(name) {|candidate, tout, nameserver|
      msg = Message.new
      msg.rd = 1
      msg.add_question(candidate, typeclass)
      unless sender = senders[[candidate, nameserver]]
        sender = senders[[candidate, nameserver]] =
          @requester.sender(msg, candidate, q, nameserver)
      end
      sender.send
      reply = reply_name = nil
      timeout(tout, ResolvTimeout) { reply, reply_name = q.pop }
      case reply.rcode
      when RCode::NoError
        extract_resources(reply, reply_name, typeclass, &proc)
        return
      when RCode::NXDomain
        raise Config::NXDomain.new(reply_name.to_s)
      else
        raise Config::OtherResolvError.new(reply_name.to_s)
      end
    }
  ensure
    @requester.delete(q)
  end
end

#extract_resources(msg, name, typeclass) ⇒ Object

:nodoc:



543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
# File 'lib/net/dns/resolv.rb', line 543

def extract_resources(msg, name, typeclass) # :nodoc:
  if typeclass < Resource::ANY
    n0 = Name.create(name)
    msg.each_answer {|n, ttl, data|
      yield data if n0 == n
    }
  end
  yielded = false
  n0 = Name.create(name)
  msg.each_answer {|n, ttl, data|
    if n0 == n
      case data
      when typeclass
        yield data
        yielded = true
      when Resource::CNAME
        n0 = data.name
      end
    end
  }
  return if yielded
  msg.each_answer {|n, ttl, data|
    if n0 == n
      case data
      when typeclass
        yield data
      end
    end
  }
end

#getaddress(name) ⇒ Object

Raises:



461
462
463
464
# File 'lib/net/dns/resolv.rb', line 461

def getaddress(name)
  each_address(name) {|address| return address}
  raise ResolvError.new("DNS result has no information for #{name}")
end

#getaddresses(name) ⇒ Object



466
467
468
469
470
# File 'lib/net/dns/resolv.rb', line 466

def getaddresses(name)
  ret = []
  each_address(name) {|address| ret << address}
  return ret
end

#getname(address) ⇒ Object

Raises:



476
477
478
479
# File 'lib/net/dns/resolv.rb', line 476

def getname(address)
  each_name(address) {|name| return name}
  raise ResolvError.new("DNS result has no information for #{address}")
end

#getnames(address) ⇒ Object



481
482
483
484
485
# File 'lib/net/dns/resolv.rb', line 481

def getnames(address)
  ret = []
  each_name(address) {|name| ret << name}
  return ret
end

#getresource(name, typeclass) ⇒ Object

Raises:



501
502
503
504
# File 'lib/net/dns/resolv.rb', line 501

def getresource(name, typeclass)
  each_resource(name, typeclass) {|resource| return resource}
  raise ResolvError.new("DNS result has no information for #{name}")
end

#getresources(name, typeclass) ⇒ Object



506
507
508
509
510
# File 'lib/net/dns/resolv.rb', line 506

def getresources(name, typeclass)
  ret = []
  each_resource(name, typeclass) {|resource| ret << resource}
  return ret
end

#lazy_initializeObject

:nodoc:



434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
# File 'lib/net/dns/resolv.rb', line 434

def lazy_initialize # :nodoc:
  @mutex.synchronize {
    unless @initialized
      @config.lazy_initialize

      if nameserver = @config.single?
        @requester = Requester::ConnectedUDP.new(nameserver)
      else
        @requester = Requester::UnconnectedUDP.new
      end

      @initialized = true
    end
  }
  self
end