Class: Resolv::DNS::Requester

Inherits:
Object
  • Object
show all
Defined in:
lib/resolv.rb

Overview

:nodoc:

Defined Under Namespace

Classes: ConnectedUDP, MDNSOneShot, RequestError, Sender, TCP, UnconnectedUDP

Instance Method Summary collapse

Constructor Details

#initialize ⇒ Requester

Returns a new instance of Requester.



708
709
710
711
# File 'lib/resolv.rb', line 708

def initialize
  @senders = {}
  @socks = nil
end

Instance Method Details

#close ⇒ Object



779
780
781
782
783
# File 'lib/resolv.rb', line 779

def close
  socks = @socks
  @socks = nil
  socks&.each(&:close)
end

#request(sender, tout) ⇒ Object



724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
# File 'lib/resolv.rb', line 724

def request(sender, tout)
  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  timelimit = start + tout
  begin
    sender.send
  rescue Errno::EHOSTUNREACH, # multi-homed IPv6 may generate this
         Errno::ENETUNREACH,
         Errno::EPIPE, # a peer that went away between requests
         Errno::ECONNRESET # the same, as Windows reports it
    send_failed
    raise ResolvTimeout
  end
  while true
    before_select = Process.clock_gettime(Process::CLOCK_MONOTONIC)
    timeout = timelimit - before_select
    if timeout <= 0
      raise ResolvTimeout
    end
    if @socks.size == 1
      select_result = @socks[0].wait_readable(timeout) ? [ @socks ] : nil
    else
      select_result = IO.select(@socks, nil, nil, timeout)
    end
    if !select_result
      after_select = Process.clock_gettime(Process::CLOCK_MONOTONIC)
      next if after_select < timelimit
      raise ResolvTimeout
    end
    begin
      reply, from = recv_reply(select_result[0], timelimit)
    rescue Errno::ECONNREFUSED, # GNU/Linux, FreeBSD
           Errno::ECONNRESET, # Windows
           EOFError
      # No name server running on the server?
      # Don't wait anymore.
      raise ResolvTimeout
    end
    begin
      msg = Message.decode(reply)
    rescue DecodeError
      next # broken DNS message ignored
    end
    if sender == sender_for(from, msg)
      break
    else
      # unexpected DNS message ignored
    end
  end
  return msg, sender.data
end

#reusable? ⇒ Boolean

Whether another request may be sent over the same transport. Only a stream transport can end up in a state that rules this out.

Returns:

  • (Boolean)


715
716
717
# File 'lib/resolv.rb', line 715

def reusable?
  true
end

#send_failed ⇒ Object

A request could not be written. Only a stream transport can be left unusable by that; see #reusable?.



721
722
# File 'lib/resolv.rb', line 721

def send_failed
end

#sender_for(addr, msg) ⇒ Object



775
776
777
# File 'lib/resolv.rb', line 775

def sender_for(addr, msg)
  @senders[[addr,msg.id]]
end