Class: DNS::Zone::RR::Record Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/dns/zone/rr/record.rb

Overview

This class is abstract.

Each RR TYPE should subclass and override: #load and ##dump

Parent class of all RR types, common resource record code lives here. Is responsible for building a Ruby object given a RR string.

Direct Known Subclasses

A, CNAME, DNSKEY, DS, HINFO, MX, NAPTR, NS, NSEC, NSEC3, NSEC3PARAM, PTR, RRSIG, SOA, SRV, SSHFP, TXT

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRecord

Returns a new instance of Record.


10
11
12
13
# File 'lib/dns/zone/rr/record.rb', line 10

def initialize
  @label = '@'
  @klass = 'IN'
end

Instance Attribute Details

#klassObject (readonly)

Returns the value of attribute klass


8
9
10
# File 'lib/dns/zone/rr/record.rb', line 8

def klass
  @klass
end

#labelObject

Returns the value of attribute label


7
8
9
# File 'lib/dns/zone/rr/record.rb', line 7

def label
  @label
end

#ttlObject

Returns the value of attribute ttl


7
8
9
# File 'lib/dns/zone/rr/record.rb', line 7

def ttl
  @ttl
end

Instance Method Details

#dumpString

Build RR zone file output.

Returns:

  • (String)

    RR zone file output


46
47
48
# File 'lib/dns/zone/rr/record.rb', line 46

def dump
  general_prefix.join(' ')
end

#general_prefixArray<String>

Returns 'general' prefix (in parts) that come before the RDATA. Used by all RR types, generates: `[<label>] [<ttl>] [<class>] <type>`

Returns:

  • (Array<String>)

    rr prefix parts


34
35
36
37
38
39
40
41
# File 'lib/dns/zone/rr/record.rb', line 34

def general_prefix
  parts = []
  parts << label
  parts << ttl if ttl
  parts << 'IN'
  parts << type
  parts
end

#load(string, options = {}) ⇒ Object

This method is abstract.

Override to update instance with RR type spesific data.

Parameters:

  • string (String)

    RR ASCII string data

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

    additional data required to correctly parse a 'whole' zone

Options Hash (options):

  • :last_label (String)

    The last label used by the previous RR

Returns:

  • (Object)

Raises:

  • (NotImplementedError)

55
56
57
# File 'lib/dns/zone/rr/record.rb', line 55

def load(string, options = {})
  raise NotImplementedError, "#load method must be implemented by subclass (#{self.class})"
end

#load_general_and_get_rdata(string, options = {}) ⇒ String

Load 'general' RR data/params and return the remaining RDATA for further parsing.

Parameters:

  • string (String)

    RR ASCII string data

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

    additional data required to correctly parse a 'whole' zone

Returns:

  • (String)

    remaining RDATA


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/dns/zone/rr/record.rb', line 64

def load_general_and_get_rdata(string, options = {})
  # strip comments, unless its escaped.
  # skip semicolons within "quote segments" (TXT records)
  string.gsub!(/((?<!\\);)(?=(?:[^"]|"[^"]*")*$).*/o, "")

  captures = string.match(DNS::Zone::RR::REGEX_RR)
  return nil unless captures

  if [' ', nil].include?(captures[:label])
    @label = options[:last_label]
  else
    @label = captures[:label]
  end

  # unroll records nested under other origins
  unrolled_origin = options[:last_origin].sub(options[:origin], '').chomp('.') if options[:last_origin]
  if unrolled_origin && !unrolled_origin.empty?
    @label = @label == '@' ? unrolled_origin : "#{@label}.#{unrolled_origin}"
  end

  @ttl = captures[:ttl]
  captures[:rdata]
end

#typeString

FIXME: should we just: `def type; 'SOA'; end` rather then do the class name convension?

Figures out TYPE of RR using class name. This means the class name must match the RR ASCII TYPE.

When called directly on the parent class (that you should never do), it will

return the string as `<type>`, for use with internal tests.

Returns:

  • (String)

    the RR type


24
25
26
27
28
# File 'lib/dns/zone/rr/record.rb', line 24

def type
  name = self.class.name.split('::').last
  return '<type>' if name == 'Record'
  name
end