Method: Net::DNS::Resolver#query

Defined in:
lib/net/dns/resolver.rb

#query(argument, type = Net::DNS::A, cls = Net::DNS::IN) ⇒ Object

Performs a DNS query for the given name. Neither the searchlist nor the default domain will be appended.

The argument list can be either a Net::DNS::Packet object or a name string plus optional type and class, which if omitted default to A and IN.

Returns a Net::DNS::Packet object.

# Executes the query with a +Packet+ object
send_packet = Net::DNS::Packet.new("host.example.com", Net::DNS::NS, Net::DNS::HS)
packet = res.query(send_packet)

# Executes the query with a host, type and cls
packet = res.query("host.example.com")
packet = res.query("host.example.com", Net::DNS::NS)
packet = res.query("host.example.com", Net::DNS::NS, Net::DNS::HS)

If the name is an IP address (Ipv4 or IPv6), in the form of a string or a IPAddr object, then an appropriate PTR query will be performed:

ip = IPAddr.new("172.16.100.2")
packet = res.query(ip)

packet = res.query("172.16.100.2")

Use packet.header.ancount or packet.answer to find out if there were any records in the answer section.



875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
# File 'lib/net/dns/resolver.rb', line 875

def query(argument, type = Net::DNS::A, cls = Net::DNS::IN)
  if @config[:nameservers].size == 0
    raise Resolver::Error, "No nameservers specified!"
  end

  method = :query_udp
  packet = if argument.kind_of? Net::DNS::Packet
    argument
  else
    make_query_packet(argument, type, cls)
  end

  # Store packet_data for performance improvements,
  # so methods don't keep on calling Packet#data
  packet_data = packet.data
  packet_size = packet_data.size

  # Choose whether use TCP, UDP or RAW
  if packet_size > @config[:packet_size] # Must use TCP, either plain or raw
    if @raw # Use raw sockets?
      info "Sending #{packet_size} bytes using TCP over RAW socket"
      method = :send_raw_tcp
    else
      info "Sending #{packet_size} bytes using TCP"
      method = :query_tcp
    end
  else # Packet size is inside the boundaries
    if @raw # Use raw sockets?
      info "Sending #{packet_size} bytes using UDP over RAW socket"
      method = :send_raw_udp
    elsif use_tcp? # User requested TCP
      info "Sending #{packet_size} bytes using TCP"
      method = :query_tcp
    else # Finally use UDP
      info "Sending #{packet_size} bytes using UDP"
      method = :query_udp
    end
  end

  if type == Net::DNS::AXFR
    if @raw
      info "AXFR query, switching to TCP over RAW socket"
      method = :send_raw_tcp
    else
      info "AXFR query, switching to TCP"
      method = :query_tcp
    end
  end

  ans = self.send(method, packet, packet_data)

  # Don't have any responses with the raw,
  # since currently raw is only used when source_address is changed
  if @raw
    return nil
  end

  if not ans
    message = "No response from nameservers list"
    # NoMethodError: undefined method `fatal' for nil:NilClass
    #@logger.fatal(message)
    warn(message)
    raise NoResponseError, message
  end

  info "Received #{ans[0].size} bytes from #{ans[1][2]+":"+ans[1][1].to_s}"
  response = Net::DNS::Packet.parse(ans[0],ans[1])

  if response.header.truncated? and not ignore_truncated?
    info "Packet truncated, retrying using TCP"
    self.use_tcp = true
    begin
      return query(argument,type,cls)
    ensure
      self.use_tcp = false
    end
  end

  return response
end