class DnsOne::ZoneSearch

Constants

IN
Name

Public Instance Methods

query(dom_name, res_class, ip_address) click to toggle source
# File lib/dns_one/zone_search.rb, line 28
def query dom_name, res_class, ip_address
    return unless dom_name =~ Util::DOM_REGEX

    dom_name = dom_name.dup
    res_class_short = Util.last_mod res_class # :A, :NS, found in conf.yml:record_sets items
    Global.logger.debug "request #{ dom_name }/#{res_class_short} from #{ip_address}..."

    records = []

    rec_set_name, from_cache = find_record_set dom_name
    Global.logger.debug "domain #{ rec_set_name ? "found, rec_set_name = '#{rec_set_name}'" : 'not found' }"
    return unless rec_set_name

    # use first record set if rec_set_name == ''
    rec_set_name = @conf.record_sets.to_h.keys.first if rec_set_name == ''
 
    rec_set = @conf.record_sets[rec_set_name]
    Global.logger.debug "record set #{ rec_set ? 'found' : 'not found' }"
    return records unless rec_set

    # TODO: move parsing logic to own class

    recs = rec_set[res_class_short.to_sym]
    Global.logger.debug "record(s) #{ recs ? 'found' : 'not found' }"

    # Loop over 1 or more
    recs = [recs]
    recs.flatten! unless res_class == IN::SOA

    recs.compact.each do |val_raw|
        val = if res_class == IN::NS
            Name.create val_raw
        elsif res_class == IN::SOA
            [0, 1].each{|i| val_raw[i] = Name.create val_raw[i] }
            val_raw
        else
            val_raw
        end
        records << OpenStruct.new(val: val, res_class: res_class, section: 'answer')
    end

    [records, from_cache]
end
setup() click to toggle source
# File lib/dns_one/zone_search.rb, line 14
def setup
    @conf = Global.conf
    check_record_sets
    @backend = set_backend
    @cache = Cache.new Global.conf.cache_max
    @ignore_subdomains_re = build_ignore_subdomains_re

    if @backend.preload_dummy?
        query 'dummy.com.br', Resolv::DNS::Resource::IN, '1.2.3.4'
    end

    self
end

Private Instance Methods

build_ignore_subdomains_re() click to toggle source
# File lib/dns_one/zone_search.rb, line 74
def build_ignore_subdomains_re
    if i = @conf.ignore_subdomains.presence
        s = i.strip.split(/\s+/).map(&:downcase).join '|'
        /^(#{ s })\./i
    end
end
check_debug_tags(dom_name) click to toggle source
# File lib/dns_one/zone_search.rb, line 124
def check_debug_tags dom_name
    use_cache = true
    if dom_name.sub!(/^NC/, '')
        use_cache = false 
    end
    [dom_name, use_cache]
end
check_record_sets() click to toggle source
# File lib/dns_one/zone_search.rb, line 132
def check_record_sets
    if @conf.record_sets.blank?
        Util.die "Record sets cannot be empty. Check file."
    end

    @conf.record_sets.each_pair do |rec_set_name, records|
        unless records[:NS] and records[:NS].length >= 1
            Util.die "Record set #{rec_set_name} is invalid. It must have at least 1 NS record."
        end
        unless records[:SOA] and records[:SOA].length == 7
            Util.die "Record set #{rec_set_name} is invalid. It must have a valid SOA record."
        end
    end
end
find_record_set(dom_name) click to toggle source
# File lib/dns_one/zone_search.rb, line 97
def find_record_set dom_name
    dom_name, use_cache = check_debug_tags dom_name
    dom_name = normalize_domain dom_name
    
    enabled_cache = use_cache && @backend.allow_cache

    if enabled_cache and rec_set = @cache.find(dom_name)
        Global.logger.debug "found in cache (#{@cache.stat})"
        [rec_set, true]
    else
        if rec_set = @backend.find(dom_name)
            @cache.add dom_name, rec_set if enabled_cache
            [rec_set, false]
        end
    end        
end
normalize_domain(dom_name) click to toggle source
# File lib/dns_one/zone_search.rb, line 114
def normalize_domain dom_name
    dom_name = dom_name.dup

    dom_name.sub! @ignore_subdomains_re, '' if @ignore_subdomains_re
    dom_name.downcase!
    dom_name.sub! /\.home$/i, ''

    dom_name
end
set_backend() click to toggle source
# File lib/dns_one/zone_search.rb, line 81
def set_backend
    if file = @conf.backend.file
        unless ::File.exists? file
            Util.die "Domain list file #{file} not found (pwd = #{Dir.pwd})."
        end
        Backend::File.new file
    elsif @conf.backend.http_bell_url
        unless @conf.backend.http_bell_record_set
            Util.die "backend.http_bell_record_set not set."
        end
        Backend::HTTPBell.new @conf.backend
    else
        Backend::DB.new @conf.backend
    end
end