dnsruby 1.55 → 1.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +96 -0
- data/Rakefile +30 -29
- data/demo/axfr.rb +93 -93
- data/demo/check_soa.rb +99 -99
- data/demo/check_zone.rb +59 -59
- data/demo/digdlv.rb +43 -43
- data/demo/digroot.rb +34 -34
- data/demo/example_recurse.rb +14 -14
- data/demo/mresolv.rb +30 -30
- data/demo/mx.rb +31 -31
- data/demo/rubydig.rb +37 -37
- data/demo/to_resolve.txt +3088 -3088
- data/demo/trace_dns.rb +46 -46
- data/lib/dnsruby.rb +161 -526
- data/lib/dnsruby/DNS.rb +305 -0
- data/lib/{Dnsruby/Cache.rb → dnsruby/cache.rb} +152 -152
- data/lib/{Dnsruby → dnsruby}/code_mapper.rb +48 -52
- data/lib/dnsruby/code_mappers.rb +295 -0
- data/lib/{Dnsruby/Config.rb → dnsruby/config.rb} +454 -454
- data/lib/{Dnsruby → dnsruby}/dnssec.rb +91 -91
- data/lib/{Dnsruby/Hosts.rb → dnsruby/hosts.rb} +125 -125
- data/lib/{Dnsruby → dnsruby}/ipv4.rb +26 -26
- data/lib/{Dnsruby → dnsruby}/ipv6.rb +42 -42
- data/lib/{Dnsruby → dnsruby}/key_cache.rb +29 -29
- data/lib/dnsruby/message/decoder.rb +164 -0
- data/lib/dnsruby/message/encoder.rb +75 -0
- data/lib/dnsruby/message/header.rb +249 -0
- data/lib/dnsruby/message/message.rb +629 -0
- data/lib/dnsruby/message/question.rb +86 -0
- data/lib/dnsruby/message/section.rb +96 -0
- data/lib/{Dnsruby → dnsruby}/name.rb +141 -141
- data/lib/dnsruby/packet_sender.rb +661 -0
- data/lib/{Dnsruby/Recursor.rb → dnsruby/recursor.rb} +235 -233
- data/lib/dnsruby/resolv.rb +113 -0
- data/lib/dnsruby/resolver.rb +1192 -0
- data/lib/dnsruby/resource/A.rb +56 -0
- data/lib/dnsruby/resource/AAAA.rb +54 -0
- data/lib/{Dnsruby → dnsruby}/resource/AFSDB.rb +68 -68
- data/lib/{Dnsruby → dnsruby}/resource/CERT.rb +105 -105
- data/lib/{Dnsruby → dnsruby}/resource/DHCID.rb +54 -54
- data/lib/dnsruby/resource/DLV.rb +27 -0
- data/lib/{Dnsruby → dnsruby}/resource/DNSKEY.rb +372 -372
- data/lib/{Dnsruby → dnsruby}/resource/DS.rb +255 -255
- data/lib/{Dnsruby → dnsruby}/resource/HINFO.rb +71 -71
- data/lib/{Dnsruby → dnsruby}/resource/HIP.rb +29 -29
- data/lib/{Dnsruby → dnsruby}/resource/IN.rb +30 -30
- data/lib/{Dnsruby → dnsruby}/resource/IPSECKEY.rb +31 -31
- data/lib/{Dnsruby → dnsruby}/resource/ISDN.rb +62 -62
- data/lib/{Dnsruby → dnsruby}/resource/KX.rb +65 -65
- data/lib/{Dnsruby → dnsruby}/resource/LOC.rb +263 -263
- data/lib/{Dnsruby → dnsruby}/resource/MINFO.rb +69 -69
- data/lib/{Dnsruby → dnsruby}/resource/MX.rb +65 -65
- data/lib/{Dnsruby → dnsruby}/resource/NAPTR.rb +98 -98
- data/lib/{Dnsruby → dnsruby}/resource/NSAP.rb +171 -171
- data/lib/dnsruby/resource/NSEC.rb +275 -0
- data/lib/dnsruby/resource/NSEC3.rb +332 -0
- data/lib/dnsruby/resource/NSEC3PARAM.rb +135 -0
- data/lib/dnsruby/resource/OPT.rb +272 -0
- data/lib/{Dnsruby → dnsruby}/resource/PX.rb +70 -70
- data/lib/{Dnsruby → dnsruby}/resource/RP.rb +75 -75
- data/lib/dnsruby/resource/RR.rb +421 -0
- data/lib/dnsruby/resource/RRSIG.rb +275 -0
- data/lib/dnsruby/resource/RRSet.rb +190 -0
- data/lib/{Dnsruby → dnsruby}/resource/RT.rb +67 -67
- data/lib/{Dnsruby → dnsruby}/resource/SOA.rb +94 -94
- data/lib/dnsruby/resource/SPF.rb +29 -0
- data/lib/dnsruby/resource/SRV.rb +112 -0
- data/lib/{Dnsruby → dnsruby}/resource/SSHFP.rb +14 -14
- data/lib/dnsruby/resource/TKEY.rb +163 -0
- data/lib/dnsruby/resource/TSIG.rb +593 -0
- data/lib/{Dnsruby → dnsruby}/resource/TXT.rb +191 -191
- data/lib/dnsruby/resource/X25.rb +55 -0
- data/lib/{Dnsruby → dnsruby}/resource/domain_name.rb +25 -25
- data/lib/{Dnsruby → dnsruby}/resource/generic.rb +80 -80
- data/lib/dnsruby/resource/resource.rb +25 -0
- data/lib/{Dnsruby → dnsruby}/select_thread.rb +148 -148
- data/lib/{Dnsruby/SingleResolver.rb → dnsruby/single_resolver.rb} +60 -60
- data/lib/{Dnsruby → dnsruby}/single_verifier.rb +344 -344
- data/lib/dnsruby/the_log.rb +44 -0
- data/lib/dnsruby/update.rb +278 -0
- data/lib/dnsruby/validator_thread.rb +124 -0
- data/lib/dnsruby/version.rb +3 -0
- data/lib/{Dnsruby → dnsruby}/zone_reader.rb +93 -93
- data/lib/{Dnsruby → dnsruby}/zone_transfer.rb +377 -377
- data/test/spec_helper.rb +16 -0
- data/test/tc_axfr.rb +31 -34
- data/test/tc_cache.rb +32 -32
- data/test/tc_dlv.rb +28 -28
- data/test/tc_dns.rb +73 -76
- data/test/tc_dnskey.rb +31 -32
- data/test/tc_dnsruby.rb +50 -44
- data/test/tc_ds.rb +36 -36
- data/test/tc_escapedchars.rb +252 -255
- data/test/tc_hash.rb +17 -21
- data/test/tc_header.rb +48 -57
- data/test/tc_hip.rb +19 -22
- data/test/tc_ipseckey.rb +18 -21
- data/test/tc_keith.rb +300 -0
- data/test/tc_message.rb +87 -0
- data/test/tc_misc.rb +83 -87
- data/test/tc_name.rb +81 -84
- data/test/tc_naptr.rb +18 -21
- data/test/tc_nsec.rb +55 -55
- data/test/tc_nsec3.rb +23 -24
- data/test/tc_nsec3param.rb +20 -21
- data/test/tc_packet.rb +90 -93
- data/test/tc_packet_unique_push.rb +48 -51
- data/test/tc_question.rb +30 -33
- data/test/tc_queue.rb +16 -17
- data/test/tc_recur.rb +16 -17
- data/test/tc_res_config.rb +38 -41
- data/test/tc_res_env.rb +29 -32
- data/test/tc_res_file.rb +26 -29
- data/test/tc_res_opt.rb +62 -65
- data/test/tc_resolver.rb +287 -242
- data/test/tc_rr-opt.rb +70 -63
- data/test/tc_rr-txt.rb +68 -71
- data/test/tc_rr-unknown.rb +45 -48
- data/test/tc_rr.rb +76 -70
- data/test/tc_rrset.rb +21 -22
- data/test/tc_rrsig.rb +19 -20
- data/test/tc_single_resolver.rb +294 -297
- data/test/tc_soak.rb +199 -202
- data/test/tc_soak_base.rb +29 -34
- data/test/tc_sshfp.rb +20 -23
- data/test/tc_tcp.rb +32 -35
- data/test/tc_tkey.rb +41 -44
- data/test/tc_tsig.rb +81 -84
- data/test/tc_update.rb +108 -111
- data/test/tc_validator.rb +29 -29
- data/test/tc_verifier.rb +81 -82
- data/test/ts_dnsruby.rb +16 -15
- data/test/ts_offline.rb +62 -63
- data/test/ts_online.rb +115 -115
- metadata +155 -90
- data/README +0 -59
- data/lib/Dnsruby/DNS.rb +0 -305
- data/lib/Dnsruby/PacketSender.rb +0 -656
- data/lib/Dnsruby/Resolver.rb +0 -1189
- data/lib/Dnsruby/TheLog.rb +0 -44
- data/lib/Dnsruby/message.rb +0 -1230
- data/lib/Dnsruby/resource/A.rb +0 -56
- data/lib/Dnsruby/resource/AAAA.rb +0 -54
- data/lib/Dnsruby/resource/DLV.rb +0 -27
- data/lib/Dnsruby/resource/NSEC.rb +0 -298
- data/lib/Dnsruby/resource/NSEC3.rb +0 -340
- data/lib/Dnsruby/resource/NSEC3PARAM.rb +0 -135
- data/lib/Dnsruby/resource/OPT.rb +0 -213
- data/lib/Dnsruby/resource/RRSIG.rb +0 -275
- data/lib/Dnsruby/resource/SPF.rb +0 -29
- data/lib/Dnsruby/resource/SRV.rb +0 -112
- data/lib/Dnsruby/resource/TKEY.rb +0 -163
- data/lib/Dnsruby/resource/TSIG.rb +0 -593
- data/lib/Dnsruby/resource/X25.rb +0 -55
- data/lib/Dnsruby/resource/resource.rb +0 -678
- data/lib/Dnsruby/update.rb +0 -278
- data/lib/Dnsruby/validator_thread.rb +0 -124
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# A Dnsruby::Question object represents a record in the
|
|
2
|
+
# question section of a DNS packet.
|
|
3
|
+
#
|
|
4
|
+
# RFC 1035 Section 4.1.2
|
|
5
|
+
module Dnsruby
|
|
6
|
+
class Question
|
|
7
|
+
|
|
8
|
+
# The Question name
|
|
9
|
+
attr_reader :qname
|
|
10
|
+
# The Question type
|
|
11
|
+
attr_reader :qtype
|
|
12
|
+
# The Question class
|
|
13
|
+
attr_reader :qclass
|
|
14
|
+
|
|
15
|
+
# Creates a question object from the domain, type, and class passed
|
|
16
|
+
# as arguments.
|
|
17
|
+
#
|
|
18
|
+
# If a String is passed in, a Name, IPv4 or IPv6 object is created.
|
|
19
|
+
#
|
|
20
|
+
# If an IPv4 or IPv6 object is used then the type is set to PTR.
|
|
21
|
+
def initialize(qname, qtype = :not_provided, qclass = :not_provided)
|
|
22
|
+
|
|
23
|
+
raise ArgumentError.new('qname must not be nil') if qname.nil?
|
|
24
|
+
|
|
25
|
+
@qtype = (qtype == :not_provided) ? Types::A : Types.new(qtype)
|
|
26
|
+
@qclass = (qclass == :not_provided) ? Classes::IN : Classes.new(qclass)
|
|
27
|
+
set_qname(qname, qtype == :not_provided)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def qtype=(qtype)
|
|
31
|
+
@qtype = Types.new(qtype)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def qclass=(qclass)
|
|
35
|
+
@qclass = Classes.new(qclass)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def set_qname(qname, write_PTR_to_qtype_if_ip = true)
|
|
39
|
+
is_ipv4_addr_string = qname.is_a?(String) && IPv4::Regex.match(qname)
|
|
40
|
+
is_ipv6_addr_string = qname.is_a?(String) && IPv6::Regex.match(qname)
|
|
41
|
+
is_ip_addr_string = is_ipv4_addr_string || is_ipv6_addr_string
|
|
42
|
+
|
|
43
|
+
is_ip_addr = [IPv4, IPv6].any? { |klass| qname.is_a?(klass) }
|
|
44
|
+
|
|
45
|
+
if is_ipv4_addr_string
|
|
46
|
+
@qname = IPv4.create(qname).to_name
|
|
47
|
+
elsif is_ipv6_addr_string
|
|
48
|
+
@qname = IPv6.create(qname).to_name
|
|
49
|
+
else
|
|
50
|
+
@qname = Name.create(qname)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# If the name looks like an IP address then do an appropriate
|
|
54
|
+
# PTR query, unless the user specified the qtype
|
|
55
|
+
if write_PTR_to_qtype_if_ip && (is_ip_addr || is_ip_addr_string)
|
|
56
|
+
@qtype = Types.PTR
|
|
57
|
+
end
|
|
58
|
+
@qname.absolute = true
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def qname=(qname)
|
|
62
|
+
set_qname(qname, true)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def ==(other)
|
|
66
|
+
other.is_a?(Question) &&
|
|
67
|
+
self.qname == other.qname &&
|
|
68
|
+
self.qtype == other.qtype &&
|
|
69
|
+
self.qclass == other.qclass
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Returns a string representation of the question record.
|
|
73
|
+
def to_s
|
|
74
|
+
"#{@qname}.\t#{@qclass.string}\t#{@qtype.string}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# For Updates, the qname field is redefined to zname (RFC2136, section 2.3)
|
|
78
|
+
alias zname qname
|
|
79
|
+
# For Updates, the qtype field is redefined to ztype (RFC2136, section 2.3)
|
|
80
|
+
alias ztype qtype
|
|
81
|
+
# For Updates, the qclass field is redefined to zclass (RFC2136, section 2.3)
|
|
82
|
+
alias zclass qclass
|
|
83
|
+
|
|
84
|
+
alias type qtype
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module Dnsruby
|
|
2
|
+
class Section < Array
|
|
3
|
+
|
|
4
|
+
def initialize(msg = nil)
|
|
5
|
+
@msg = msg
|
|
6
|
+
super(0)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Return the rrset of the specified type in this section
|
|
10
|
+
def rrset(name, type=Types.A, klass=Classes::IN)
|
|
11
|
+
rrs = select{|rr|
|
|
12
|
+
type_ok = (rr.type==type)
|
|
13
|
+
if rr.type == Types::RRSIG
|
|
14
|
+
type_ok = (rr.type_covered == type)
|
|
15
|
+
end
|
|
16
|
+
unless /\.\z/ =~ name.to_s
|
|
17
|
+
name = name.to_s + '.'
|
|
18
|
+
end
|
|
19
|
+
type_ok && (rr.klass == klass) && (rr.name.to_s(true).downcase == name.to_s().downcase)
|
|
20
|
+
}
|
|
21
|
+
rrset = RRSet.new()
|
|
22
|
+
rrs.each do |rr|
|
|
23
|
+
rrset.add(rr)
|
|
24
|
+
end
|
|
25
|
+
rrset
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Return an array of all the rrsets in the section
|
|
29
|
+
def rrsets(type = nil, include_opt = false)
|
|
30
|
+
if type && !(Types === type)
|
|
31
|
+
type = Types.new(type)
|
|
32
|
+
end
|
|
33
|
+
ret = []
|
|
34
|
+
each do |rr|
|
|
35
|
+
next if (!include_opt && (rr.type == Types::OPT))
|
|
36
|
+
# if (type)
|
|
37
|
+
# next if ((rr.type == Types.RRSIG) && (type != Types.RRSIG) && (rr.type_covered != type))
|
|
38
|
+
# next if (rr.type != type)
|
|
39
|
+
# end
|
|
40
|
+
if (type)
|
|
41
|
+
# if this is an rrsig type, then :
|
|
42
|
+
# only include it if the type_covered is the type requested,
|
|
43
|
+
# OR if the type requested is an RRSIG
|
|
44
|
+
if rr.type == Types::RRSIG
|
|
45
|
+
if (rr.type_covered == type) || (type == Types::RRSIG)
|
|
46
|
+
else
|
|
47
|
+
next
|
|
48
|
+
end
|
|
49
|
+
# next if ((rr.type_covered != type) || (type != Types.RRSIG))
|
|
50
|
+
elsif rr.type != type
|
|
51
|
+
next
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
found_rrset = false
|
|
56
|
+
ret.each do |rrset|
|
|
57
|
+
found_rrset = rrset.add(rr)
|
|
58
|
+
break if found_rrset
|
|
59
|
+
end
|
|
60
|
+
unless found_rrset
|
|
61
|
+
ret.push(RRSet.new(rr))
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
ret
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def ==(other)
|
|
68
|
+
return false unless (other.instance_of?(Message::Section))
|
|
69
|
+
return false if other.rrsets(nil, true).length != self.rrsets(nil, true).length
|
|
70
|
+
|
|
71
|
+
otherrrsets = other.rrsets(nil, true)
|
|
72
|
+
self.rrsets(nil, true).each {|rrset|
|
|
73
|
+
return false unless otherrrsets.include?(rrset)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
true
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def remove_rrset(name, type)
|
|
80
|
+
# Remove all RRs with the name and type from the section.
|
|
81
|
+
# Need to worry about header counts here - can we get Message to
|
|
82
|
+
# update the counts itself, rather than the section worrying about it?
|
|
83
|
+
rrs_to_delete = []
|
|
84
|
+
each do |rr|
|
|
85
|
+
next if rr.rr_type == Types::OPT
|
|
86
|
+
if (rr.name.to_s.downcase == name.to_s.downcase) &&
|
|
87
|
+
((rr.type == type) ||
|
|
88
|
+
((rr.type == Types::RRSIG) && (rr.type_covered == type)))
|
|
89
|
+
rrs_to_delete.push(rr)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
rrs_to_delete.each { |rr| delete(rr) }
|
|
93
|
+
@msg.update_counts if @msg
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
#Copyright 2007 Nominet UK
|
|
3
|
-
#
|
|
4
|
-
#Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
#you may not use this file except in compliance with the License.
|
|
6
|
-
#You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
#Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
#distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
#See the License for the specific language governing permissions and
|
|
14
|
-
#limitations under the License.
|
|
15
|
-
|
|
1
|
+
# --
|
|
2
|
+
# Copyright 2007 Nominet UK
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
# ++
|
|
16
16
|
module Dnsruby
|
|
17
|
-
|
|
18
|
-
#
|
|
19
|
-
#A representation of a DNS name
|
|
20
|
-
#(RFC1035, section 3.1)
|
|
21
|
-
#
|
|
22
|
-
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
#
|
|
17
|
+
# == Dnsruby::Name class
|
|
18
|
+
#
|
|
19
|
+
# A representation of a DNS name
|
|
20
|
+
# (RFC1035, section 3.1)
|
|
21
|
+
#
|
|
22
|
+
# == methods
|
|
23
|
+
#
|
|
24
|
+
# * Name::create(namestring)
|
|
25
|
+
# * Name#absolute?
|
|
26
|
+
# * Name#wild?
|
|
27
|
+
# * Name#subdomain_of?(other)
|
|
28
|
+
# * Name#labels
|
|
29
|
+
#
|
|
30
30
|
class Name
|
|
31
31
|
include Comparable
|
|
32
32
|
MaxNameLength=255
|
|
33
|
-
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
|
|
39
|
-
#Creates a new Dnsruby::Name from +arg+. +arg+ can be :
|
|
40
|
-
#
|
|
41
|
-
|
|
42
|
-
|
|
33
|
+
# --
|
|
34
|
+
# A Name is a collection of Labels. Each label is presentation-formatted
|
|
35
|
+
# When a Name is wire-encoded, the label array is walked, and each label is wire-encoded.
|
|
36
|
+
# When a Name is unencoded, each label is unencoded, and added to the Name collection of labels.
|
|
37
|
+
# When a Name is made from a string, the Name is split into Labels.
|
|
38
|
+
# ++
|
|
39
|
+
# Creates a new Dnsruby::Name from +arg+. +arg+ can be :
|
|
40
|
+
#
|
|
41
|
+
# * Name:: returns +arg+
|
|
42
|
+
# * String:: returns a new Name
|
|
43
43
|
def self.create(arg)
|
|
44
44
|
case arg
|
|
45
45
|
when Name
|
|
46
46
|
return Name.new(arg.labels, arg.absolute?)
|
|
47
47
|
when String
|
|
48
|
-
#
|
|
48
|
+
# arg.gsub!(/\.$/o, "")
|
|
49
49
|
if (arg==".")
|
|
50
50
|
return Name.new([],true)
|
|
51
51
|
end
|
|
@@ -53,14 +53,14 @@ module Dnsruby
|
|
|
53
53
|
return Name.new([],false)
|
|
54
54
|
end
|
|
55
55
|
return Name.new(split_escaped(arg), /\.\z/ =~ arg ? true : false)
|
|
56
|
-
#
|
|
56
|
+
# return Name.new(Label.split(arg), /\.\z/ =~ arg ? true : false)
|
|
57
57
|
when Array
|
|
58
58
|
return Name.new(arg, /\.\z/ =~ (arg.last ? ((arg.last.kind_of?String)?arg.last : arg.last.string) : arg.last) ? true : false)
|
|
59
|
-
else
|
|
59
|
+
else
|
|
60
60
|
raise ArgumentError.new("cannot interpret as DNS name: #{arg.inspect}")
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
def self.split_escaped(arg) #:nodoc: all
|
|
65
65
|
encodedlabels = name2encodedlabels(arg)
|
|
66
66
|
return encodedlabels
|
|
@@ -71,37 +71,37 @@ module Dnsruby
|
|
|
71
71
|
labels = encodedlabels.each {|el| Name.decode(el.to_s)}
|
|
72
72
|
return labels
|
|
73
73
|
end
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
attr_accessor :labels
|
|
76
|
-
|
|
77
|
-
#This method should only be called internally.
|
|
78
|
-
#Use Name::create to create a new Name
|
|
76
|
+
|
|
77
|
+
# This method should only be called internally.
|
|
78
|
+
# Use Name::create to create a new Name
|
|
79
79
|
def initialize(labels, absolute=true) #:nodoc: all
|
|
80
80
|
total_length=labels.length-1
|
|
81
|
-
labels.each do |l|
|
|
81
|
+
labels.each do |l|
|
|
82
82
|
if (!l.kind_of?Label)
|
|
83
83
|
raise ArgumentError.new("Name::new called with non-labels. Use Name::create instead?")
|
|
84
84
|
end
|
|
85
|
-
total_length+=l.length
|
|
85
|
+
total_length+=l.length
|
|
86
86
|
end
|
|
87
|
-
if (total_length > MaxNameLength)
|
|
87
|
+
if (total_length > MaxNameLength)
|
|
88
88
|
raise ResolvError.new("Name length is #{total_length}, greater than max of #{MaxNameLength} octets!")
|
|
89
89
|
end
|
|
90
90
|
@labels = labels
|
|
91
91
|
@absolute = absolute
|
|
92
92
|
end
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
def downcase
|
|
95
95
|
labels = []
|
|
96
96
|
@labels.each do |label| labels << Label.new(label.downcase) end
|
|
97
97
|
return Name.new(labels)
|
|
98
98
|
end
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
def inspect # :nodoc:
|
|
101
101
|
"#<#{self.class}: #{self.to_s}#{@absolute ? '.' : ''}>"
|
|
102
102
|
end
|
|
103
|
-
|
|
104
|
-
#Returns true if this Name is absolute
|
|
103
|
+
|
|
104
|
+
# Returns true if this Name is absolute
|
|
105
105
|
def absolute?
|
|
106
106
|
return @absolute
|
|
107
107
|
end
|
|
@@ -114,8 +114,8 @@ module Dnsruby
|
|
|
114
114
|
n = Name.new(self.labels()[1, self.labels.length-1], self.absolute?)
|
|
115
115
|
return n
|
|
116
116
|
end
|
|
117
|
-
|
|
118
|
-
#Is this name a wildcard?
|
|
117
|
+
|
|
118
|
+
# Is this name a wildcard?
|
|
119
119
|
def wild?
|
|
120
120
|
if (labels.length == 0)
|
|
121
121
|
return false
|
|
@@ -123,9 +123,9 @@ module Dnsruby
|
|
|
123
123
|
return (labels[0].string == '*')
|
|
124
124
|
end
|
|
125
125
|
|
|
126
|
-
#
|
|
126
|
+
# Return the canonical form of this name (RFC 4034 section 6.2)
|
|
127
127
|
def canonical
|
|
128
|
-
#
|
|
128
|
+
#
|
|
129
129
|
return MessageEncoder.new {|msg|
|
|
130
130
|
msg.put_name(self, true)
|
|
131
131
|
}.to_s
|
|
@@ -133,7 +133,7 @@ module Dnsruby
|
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
def <=>(other)
|
|
136
|
-
#
|
|
136
|
+
# return -1 if other less than us, +1 if greater than us
|
|
137
137
|
return 0 if (canonical == other.canonical)
|
|
138
138
|
if (canonically_before(other))
|
|
139
139
|
return +1
|
|
@@ -145,20 +145,20 @@ module Dnsruby
|
|
|
145
145
|
if (!(Name === n))
|
|
146
146
|
n = Name.create(n)
|
|
147
147
|
end
|
|
148
|
-
#
|
|
149
|
-
#
|
|
150
|
-
#
|
|
151
|
-
#individual labels as unsigned left-justified octet strings. The
|
|
152
|
-
#absence of a octet sorts before a zero value octet, and uppercase
|
|
153
|
-
#US-ASCII letters are treated as if they were lowercase US-ASCII
|
|
154
|
-
#letters.
|
|
155
|
-
#To compute the canonical ordering of a set of DNS names, start by
|
|
156
|
-
#sorting the names according to their most significant (rightmost)
|
|
157
|
-
#labels. For names in which the most significant label is identical,
|
|
158
|
-
#continue sorting according to their next most significant label, and
|
|
159
|
-
#so forth.
|
|
160
|
-
|
|
161
|
-
#
|
|
148
|
+
# Work out whether this name is canonically before the passed Name
|
|
149
|
+
# RFC 4034 section 6.1
|
|
150
|
+
# For the purposes of DNS security, owner names are ordered by treating
|
|
151
|
+
# individual labels as unsigned left-justified octet strings. The
|
|
152
|
+
# absence of a octet sorts before a zero value octet, and uppercase
|
|
153
|
+
# US-ASCII letters are treated as if they were lowercase US-ASCII
|
|
154
|
+
# letters.
|
|
155
|
+
# To compute the canonical ordering of a set of DNS names, start by
|
|
156
|
+
# sorting the names according to their most significant (rightmost)
|
|
157
|
+
# labels. For names in which the most significant label is identical,
|
|
158
|
+
# continue sorting according to their next most significant label, and
|
|
159
|
+
# so forth.
|
|
160
|
+
|
|
161
|
+
# Get the list of labels for both names, and then swap them
|
|
162
162
|
my_labels = @labels.reverse
|
|
163
163
|
other_labels = n.labels.reverse
|
|
164
164
|
my_labels.each_index {|i|
|
|
@@ -170,23 +170,23 @@ module Dnsruby
|
|
|
170
170
|
}
|
|
171
171
|
return true
|
|
172
172
|
end
|
|
173
|
-
|
|
173
|
+
|
|
174
174
|
def ==(other) # :nodoc:
|
|
175
175
|
return false if other.class != Name
|
|
176
176
|
return @labels == other.labels && @absolute == other.absolute?
|
|
177
177
|
end
|
|
178
178
|
alias eql? == # :nodoc:
|
|
179
|
-
|
|
180
|
-
#
|
|
181
|
-
#
|
|
182
|
-
#
|
|
183
|
-
#
|
|
184
|
-
#
|
|
185
|
-
#
|
|
186
|
-
#
|
|
187
|
-
#
|
|
188
|
-
#
|
|
189
|
-
#
|
|
179
|
+
|
|
180
|
+
# Tests subdomain-of relation : returns true if this name
|
|
181
|
+
# is a subdomain of +other+.
|
|
182
|
+
#
|
|
183
|
+
# domain = Resolv::Name.create("y.z")
|
|
184
|
+
# p Resolv::Name.create("w.x.y.z").subdomain_of?(domain) #=> true
|
|
185
|
+
# p Resolv::Name.create("x.y.z").subdomain_of?(domain) #=> true
|
|
186
|
+
# p Resolv::Name.create("y.z").subdomain_of?(domain) #=> false
|
|
187
|
+
# p Resolv::Name.create("z").subdomain_of?(domain) #=> false
|
|
188
|
+
# p Resolv::Name.create("x.y.z.").subdomain_of?(domain) #=> false
|
|
189
|
+
# p Resolv::Name.create("w.z").subdomain_of?(domain) #=> false
|
|
190
190
|
def subdomain_of?(other)
|
|
191
191
|
raise ArgumentError, "not a domain name: #{other.inspect}" unless Name === other
|
|
192
192
|
return false if @absolute != other.absolute?
|
|
@@ -194,33 +194,33 @@ module Dnsruby
|
|
|
194
194
|
return false if @labels.length <= other_len
|
|
195
195
|
return @labels[-other_len, other_len] == other.to_a
|
|
196
196
|
end
|
|
197
|
-
|
|
197
|
+
|
|
198
198
|
def hash # :nodoc:
|
|
199
199
|
return @labels.hash ^ @absolute.hash
|
|
200
200
|
end
|
|
201
|
-
|
|
201
|
+
|
|
202
202
|
def to_a #:nodoc: all
|
|
203
203
|
return @labels
|
|
204
204
|
end
|
|
205
|
-
|
|
205
|
+
|
|
206
206
|
def length #:nodoc: all
|
|
207
207
|
return @labels.length
|
|
208
208
|
end
|
|
209
|
-
|
|
209
|
+
|
|
210
210
|
def [](i) #:nodoc: all
|
|
211
211
|
return @labels[i]
|
|
212
212
|
end
|
|
213
|
-
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
#
|
|
213
|
+
|
|
214
|
+
# returns the domain name as a string.
|
|
215
|
+
#
|
|
216
|
+
# The domain name doesn't have a trailing dot even if the name object is
|
|
217
|
+
# absolute.
|
|
218
|
+
#
|
|
219
|
+
# Example :
|
|
220
|
+
#
|
|
221
|
+
# p Resolv::Name.create("x.y.z.").to_s #=> "x.y.z"
|
|
222
|
+
# p Resolv::Name.create("x.y.z").to_s #=> "x.y.z"
|
|
218
223
|
#
|
|
219
|
-
# Example :
|
|
220
|
-
#
|
|
221
|
-
# p Resolv::Name.create("x.y.z.").to_s #=> "x.y.z"
|
|
222
|
-
# p Resolv::Name.create("x.y.z").to_s #=> "x.y.z"
|
|
223
|
-
#
|
|
224
224
|
def to_s(include_absolute=false)
|
|
225
225
|
ret = to_str(@labels)
|
|
226
226
|
if (@absolute && include_absolute)
|
|
@@ -233,18 +233,18 @@ module Dnsruby
|
|
|
233
233
|
ls =[]
|
|
234
234
|
labels.each {|el| ls.push(Name.decode(el.to_s))}
|
|
235
235
|
return ls.join('.')
|
|
236
|
-
#
|
|
236
|
+
# return @labels.collect{|l| (l.kind_of?String) ? l : l.string}.join('.')
|
|
237
237
|
end
|
|
238
|
-
|
|
239
|
-
#
|
|
240
|
-
#
|
|
241
|
-
#
|
|
242
|
-
#
|
|
243
|
-
#
|
|
244
|
-
#
|
|
245
|
-
#
|
|
238
|
+
|
|
239
|
+
# Utility function
|
|
240
|
+
#
|
|
241
|
+
# name2labels to translate names from presentation format into an
|
|
242
|
+
# array of "wire-format" labels.
|
|
243
|
+
# in: dName a string with a domain name in presentation format (1035
|
|
244
|
+
# sect 5.1)
|
|
245
|
+
# out: an array of labels in wire format.
|
|
246
246
|
def self.name2encodedlabels (dName) #:nodoc: all
|
|
247
|
-
#
|
|
247
|
+
# Check for "\" in the name : If there, then decode properly - otherwise, cheat and split on "."
|
|
248
248
|
if (dName.index("\\"))
|
|
249
249
|
names=[]
|
|
250
250
|
j=0;
|
|
@@ -252,7 +252,7 @@ module Dnsruby
|
|
|
252
252
|
names[j],dName = encode(dName)
|
|
253
253
|
j+=1
|
|
254
254
|
end
|
|
255
|
-
|
|
255
|
+
|
|
256
256
|
return names
|
|
257
257
|
else
|
|
258
258
|
labels = []
|
|
@@ -262,14 +262,14 @@ module Dnsruby
|
|
|
262
262
|
return labels
|
|
263
263
|
end
|
|
264
264
|
end
|
|
265
|
-
|
|
265
|
+
|
|
266
266
|
def self.decode(wire) #:nodoc: all
|
|
267
267
|
presentation=""
|
|
268
268
|
length=wire.length
|
|
269
|
-
#
|
|
270
|
-
#
|
|
271
|
-
#
|
|
272
|
-
|
|
269
|
+
# There must be a nice regexp to do this.. but since I failed to
|
|
270
|
+
# find one I scan the name string until I find a '\', at that time
|
|
271
|
+
# I start looking forward and do the magic.
|
|
272
|
+
|
|
273
273
|
i=0;
|
|
274
274
|
|
|
275
275
|
unpacked = wire.unpack("C*")
|
|
@@ -300,20 +300,20 @@ module Dnsruby
|
|
|
300
300
|
end
|
|
301
301
|
|
|
302
302
|
return presentation
|
|
303
|
-
#
|
|
303
|
+
# return Label.new(presentation)
|
|
304
304
|
end
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
#
|
|
309
|
-
#
|
|
310
|
-
#
|
|
311
|
-
#
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
# wire,leftover=presentation2wire(leftover)
|
|
309
|
+
# Will parse the input presentation format and return everything before
|
|
310
|
+
# the first non-escaped "." in the first element of the return array and
|
|
311
|
+
# all that has not been parsed yet in the 2nd argument.
|
|
312
312
|
def self.encode(presentation) #:nodoc: all
|
|
313
313
|
presentation=presentation.to_s
|
|
314
314
|
wire="";
|
|
315
315
|
length=presentation.length;
|
|
316
|
-
|
|
316
|
+
|
|
317
317
|
i=0;
|
|
318
318
|
|
|
319
319
|
while (i < length )
|
|
@@ -323,9 +323,9 @@ module Dnsruby
|
|
|
323
323
|
return Label.new(wire),endstring
|
|
324
324
|
end
|
|
325
325
|
if (c == 92) # ord'\\'
|
|
326
|
-
#backslash found
|
|
326
|
+
# backslash found
|
|
327
327
|
pos = i+1
|
|
328
|
-
#
|
|
328
|
+
# pos sets where next pattern matching should start
|
|
329
329
|
if (presentation.index(/\G(\d\d\d)/o, pos))
|
|
330
330
|
wire=wire+[$1.to_i].pack("C")
|
|
331
331
|
i=i+3
|
|
@@ -353,30 +353,30 @@ module Dnsruby
|
|
|
353
353
|
end
|
|
354
354
|
i=i+1
|
|
355
355
|
end
|
|
356
|
-
|
|
356
|
+
|
|
357
357
|
return Label.new(wire)
|
|
358
358
|
end
|
|
359
|
-
|
|
360
|
-
#
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
#
|
|
365
|
-
#(RFC1035, section 3.1)
|
|
366
|
-
#
|
|
359
|
+
|
|
360
|
+
# end
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
# == Dnsruby::Label class
|
|
364
|
+
#
|
|
365
|
+
# (RFC1035, section 3.1)
|
|
366
|
+
#
|
|
367
367
|
class Label
|
|
368
368
|
include Comparable
|
|
369
369
|
MaxLabelLength = 63
|
|
370
370
|
@@max_length=MaxLabelLength
|
|
371
|
-
#
|
|
371
|
+
# Split a Name into its component Labels
|
|
372
372
|
def self.split(arg)
|
|
373
373
|
return Name.split(arg)
|
|
374
374
|
end
|
|
375
|
-
|
|
375
|
+
|
|
376
376
|
def self.set_max_length(l)
|
|
377
377
|
@@max_length=l
|
|
378
378
|
end
|
|
379
|
-
|
|
379
|
+
|
|
380
380
|
def initialize(string)
|
|
381
381
|
if (string.length > @@max_length)
|
|
382
382
|
raise ResolvError.new("Label too long (#{string.length}, max length=#{MaxLabelLength}). Label = #{string}")
|
|
@@ -386,15 +386,15 @@ module Dnsruby
|
|
|
386
386
|
@string_length = string.length
|
|
387
387
|
end
|
|
388
388
|
attr_reader :string, :downcase
|
|
389
|
-
|
|
389
|
+
|
|
390
390
|
def to_s
|
|
391
391
|
return @string.to_s # + "."
|
|
392
392
|
end
|
|
393
|
-
|
|
393
|
+
|
|
394
394
|
def length
|
|
395
395
|
return @string_length
|
|
396
396
|
end
|
|
397
|
-
|
|
397
|
+
|
|
398
398
|
def inspect
|
|
399
399
|
return "#<#{self.class} #{self.to_s}>"
|
|
400
400
|
end
|
|
@@ -403,7 +403,7 @@ module Dnsruby
|
|
|
403
403
|
return (@downcase <=> other.downcase)
|
|
404
404
|
end
|
|
405
405
|
|
|
406
|
-
|
|
406
|
+
|
|
407
407
|
def ==(other)
|
|
408
408
|
return @downcase == other.downcase
|
|
409
409
|
end
|