Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions lib/dns/zone/rr/record.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Parent class of all RR types, common resource record code lives here.
# Is responsible for building a Ruby object given a RR string.
#
# @abstract Each RR TYPE should subclass and override: {#load} and #{dump}
# @abstract Each RR TYPE should subclass and override: {#load} and #{dump}
class DNS::Zone::RR::Record

attr_accessor :label, :ttl
Expand Down Expand Up @@ -69,16 +69,23 @@ def load_general_and_get_rdata(string, options = {})
captures = string.match(DNS::Zone::RR::REGEX_RR)
return nil unless captures

if [' ', nil].include?(captures[:label])
unrolled_origin = options[:last_origin]
.sub(options[:origin], '')
.chomp('.') if options[:last_origin]

@label = captures[:label]

if [' ', nil].include?(@label)
# Empty labels indicate to use the previous value
@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}"
elsif @label == '@' && unrolled_origin && !unrolled_origin.empty?
# '@' and an unrolled origin set the current origin
@label = unrolled_origin

elsif unrolled_origin && !unrolled_origin.empty?
# Set the 'sub' $origin
@label = "#{@label}.#{unrolled_origin}"
end

@ttl = captures[:ttl]
Expand Down
37 changes: 37 additions & 0 deletions test/zone_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,25 @@ class ZoneTest < DNS::Zone::TestCase
@ 3600 A 1.1.1.1
app1 60 A 4.3.2.1

EOL

# basic zone file example
ZONE_FILE_MULTIPLE_ORIGINS_MISSING_ATS_EXAMPLE =<<-EOL
$ORIGIN lividpenguin.com.
$TTL 3d
@ IN SOA ns0.lividpenguin.com. luke.lividpenguin.com. (
2013101406 ; zone serial number
12h ; refresh ttl
15m ; retry ttl
3w ; expiry ttl
3h ; minimum ttl
)

$ORIGIN sub.lividpenguin.com.
@ 60 A 1.2.3.4
60 TXT "foo"
app1 60 A 4.3.2.1
60 TXT "bar"
EOL

def test_create_new_instance
Expand Down Expand Up @@ -200,6 +219,24 @@ def test_load_multiple_origins
assert_equal '4.3.2.1', zone.records[11].address
end

def test_load_multiple_origins_with_missing_ats
zone = DNS::Zone.load(ZONE_FILE_MULTIPLE_ORIGINS_MISSING_ATS_EXAMPLE)
assert_equal 'lividpenguin.com.', zone.origin
assert_equal 5, zone.records.length, 'we should have multiple records (including SOA)'
assert_equal 'A', zone.records[1].type
assert_equal 'sub', zone.records[1].label
assert_equal '1.2.3.4', zone.records[1].address
assert_equal 'TXT', zone.records[2].type
assert_equal 'sub', zone.records[2].label
assert_equal 'foo', zone.records[2].text
assert_equal 'A', zone.records[3].type
assert_equal 'app1.sub', zone.records[3].label
assert_equal '4.3.2.1', zone.records[3].address
assert_equal 'TXT', zone.records[4].type
assert_equal 'app1.sub', zone.records[4].label
assert_equal 'bar', zone.records[4].text
end

def test_extract_entry_from_one_line
entries = DNS::Zone.extract_entries(%Q{maiow IN TXT "purr"})
assert_equal 1, entries.length, 'we should have 1 entry'
Expand Down