Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/proto/dns/cached_resolver.rb
Views: 11704
# -*- coding: binary -*-12require 'net/dns/resolver'34module Rex5module Proto6module DNS78##9# Provides Rex::Sockets compatible version of Net::DNS::Resolver10# Modified to work with Dnsruby::Messages, their resolvers are too heavy11##12class CachedResolver < Resolver13include Rex::Proto::DNS::Constants14attr_accessor :cache1516#17# Initialize resolver with cache18#19# @param config [Hash] Resolver config20#21# @return [nil]22def initialize(config = {})23dns_cache_no_start = config.delete(:dns_cache_no_start)24super(config)25self.cache = Rex::Proto::DNS::Cache.new26self.cache.start unless dns_cache_no_start27return28end2930#31# Attempt to find answers to query in DNS cache; failing that,32# send remainder of DNS queries over appropriate transport and33# cache answers before returning to caller.34#35# @param argument [Object] An object holding the DNS message to be processed.36# @param type [Fixnum] Type of record to look up37# @param cls [Fixnum] Class of question to look up38#39# @return [Dnsruby::Message, nil] DNS response on success, nil on failure.40def send(argument, type = Dnsruby::Types::A, cls = Dnsruby::Classes::IN)41case argument42when Dnsruby::Message43req = argument44when Net::DNS::Packet, Resolv::DNS::Message45req = Rex::Proto::DNS::Packet.encode_drb(argument)46else47net_packet = make_query_packet(argument,type,cls)48# This returns a Net::DNS::Packet. Convert to Dnsruby::Message for consistency49req = Rex::Proto::DNS::Packet.encode_drb(net_packet)50end51resolve = req.dup52# Find cached items, remove request from resolved packet53req.question.each do |ques|54cached = self.cache.find(ques.qname, ques.qtype.to_s)55next if cached.empty?56req.instance_variable_set(:@answer, (req.answer + cached).uniq)57resolve.question.delete(ques)58end59# Resolve remaining requests, cache responses60if resolve.question.count > 061resolved = super(resolve, type)62req.instance_variable_set(:@answer, (req.answer + resolved.answer).uniq)63resolved.answer.each do |ans|64self.cache.cache_record(ans)65end66end67# Finalize answers in response68# Check for empty response prior to sending69req.header.rcode = Dnsruby::RCode::NOERROR if req.answer.size < 170req.header.qr = true # Set response bit71return req72end73end74end75end76end777879