Class: Rex::Proto::DNS::CachedResolver

Inherits:
Resolver
  • Object
show all
Includes:
Constants
Defined in:
lib/rex/proto/dns/cached_resolver.rb

Overview

Provides Rex::Sockets compatible version of Net::DNS::Resolver Modified to work with Dnsruby::Messages, their resolvers are too heavy

Constant Summary

Constants included from Constants

Rex::Proto::DNS::Constants::MATCH_FQDN, Rex::Proto::DNS::Constants::MATCH_HOSTNAME

Constants inherited from Resolver

Resolver::Defaults

Instance Attribute Summary collapse

Attributes inherited from Resolver

#comm, #context, #static_hostnames

Instance Method Summary collapse

Methods inherited from Resolver

default_config_file, #proxies, #proxies=, #query, #search, #send_tcp, #send_udp, #upstream_resolvers_for_packet, #upstream_resolvers_for_query

Constructor Details

#initialize(config = {}) ⇒ nil

Initialize resolver with cache

Parameters:

  • config (Hash) (defaults to: {})

    Resolver config

[View source] [View on GitHub]

23
24
25
26
27
28
29
# File 'lib/rex/proto/dns/cached_resolver.rb', line 23

def initialize(config = {})
  dns_cache_no_start = config.delete(:dns_cache_no_start)
  super(config)
  self.cache = Rex::Proto::DNS::Cache.new
  self.cache.start unless dns_cache_no_start
  return
end

Instance Attribute Details

#cacheObject

Returns the value of attribute cache.

[View on GitHub]

15
16
17
# File 'lib/rex/proto/dns/cached_resolver.rb', line 15

def cache
  @cache
end

Instance Method Details

#send(argument, type = Dnsruby::Types::A, cls = Dnsruby::Classes::IN) ⇒ Dnsruby::Message?

Attempt to find answers to query in DNS cache; failing that, send remainder of DNS queries over appropriate transport and cache answers before returning to caller.

Parameters:

  • argument (Object)

    An object holding the DNS message to be processed.

  • type (Fixnum) (defaults to: Dnsruby::Types::A)

    Type of record to look up

  • cls (Fixnum) (defaults to: Dnsruby::Classes::IN)

    Class of question to look up

Returns:

  • (Dnsruby::Message, nil)

    DNS response on success, nil on failure.

[View source] [View on GitHub]

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/rex/proto/dns/cached_resolver.rb', line 41

def send(argument, type = Dnsruby::Types::A, cls = Dnsruby::Classes::IN)
  case argument
  when Dnsruby::Message
    req = argument
  when Net::DNS::Packet, Resolv::DNS::Message
    req = Rex::Proto::DNS::Packet.encode_drb(argument)
  else
    net_packet = make_query_packet(argument,type,cls)
    # This returns a Net::DNS::Packet. Convert to Dnsruby::Message for consistency
    req = Rex::Proto::DNS::Packet.encode_drb(net_packet)
  end
  resolve = req.dup
  # Find cached items, remove request from resolved packet
  req.question.each do |ques|
    cached = self.cache.find(ques.qname, ques.qtype.to_s)
    next if cached.empty?
    req.instance_variable_set(:@answer, (req.answer + cached).uniq)
    resolve.question.delete(ques)
  end
  # Resolve remaining requests, cache responses
  if resolve.question.count > 0
    resolved = super(resolve, type)
    req.instance_variable_set(:@answer, (req.answer + resolved.answer).uniq)
    resolved.answer.each do |ans|
      begin
        self.cache.cache_record(ans)
      rescue StandardError => e
        elog('Failed to cache the DNS answer', error: e)
      end
    end
  end
  # Finalize answers in response
  # Check for empty response prior to sending
  req.header.rcode = Dnsruby::RCode::NOERROR if req.answer.size < 1
  req.header.qr = true # Set response bit
  return req
end