Class: Dnsruby::Name
Overview
Dnsruby::Name class
A representation of a DNS name (RFC1035, section 3.1)
methods
-
Name::create(namestring)
-
Name#absolute?
-
Name#wild?
-
Name#subdomain_of?(other)
-
Name#labels
Defined Under Namespace
Classes: Label
Constant Summary collapse
- MaxNameLength =
255
Instance Attribute Summary collapse
-
#labels ⇒ Object
Returns the value of attribute labels.
Class Method Summary collapse
-
.create(arg) ⇒ Object
– A Name is a collection of Labels.
-
.decode(wire) ⇒ Object
:nodoc: all.
-
.encode(presentation) ⇒ Object
wire,leftover=presentation2wire(leftover) Will parse the input presentation format and return everything before the first non-escaped “.” in the first element of the return array and all that has not been parsed yet in the 2nd argument.
-
.name2encodedlabels(dName) ⇒ Object
Utility function.
- .split(name) ⇒ Object
-
.split_escaped(arg) ⇒ Object
:nodoc: all.
Instance Method Summary collapse
- #<=>(other) ⇒ Object
-
#==(other) ⇒ Object
(also: #eql?)
:nodoc:.
-
#[](i) ⇒ Object
:nodoc: all.
-
#absolute=(on) ⇒ Object
:nodoc:.
-
#absolute? ⇒ Boolean
Returns true if this Name is absolute.
-
#canonical ⇒ Object
Return the canonical form of this name (RFC 4034 section 6.2).
- #canonically_before(n) ⇒ Object
- #downcase ⇒ Object
-
#hash ⇒ Object
:nodoc:.
-
#initialize(labels, absolute = true) ⇒ Name
constructor
This method should only be called internally.
-
#inspect ⇒ Object
:nodoc:.
-
#length ⇒ Object
:nodoc: all.
-
#strip_label ⇒ Object
:nodoc:.
-
#subdomain_of?(other) ⇒ Boolean
Tests subdomain-of relation : returns true if this name is a subdomain of
other
. -
#to_a ⇒ Object
:nodoc: all.
-
#to_s(include_absolute = false) ⇒ Object
returns the domain name as a string.
-
#to_str(labels) ⇒ Object
:nodoc: all.
-
#wild? ⇒ Boolean
Is this name a wildcard?.
Constructor Details
#initialize(labels, absolute = true) ⇒ Name
This method should only be called internally. Use Name::create to create a new Name
79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/dnsruby/name.rb', line 79 def initialize(labels, absolute=true) #:nodoc: all total_length=labels.length-1 labels.each do |l| if (!l.kind_of?Label) raise ArgumentError.new("Name::new called with non-labels. Use Name::create instead?") end total_length+=l.length end if (total_length > MaxNameLength) raise ResolvError.new("Name length is #{total_length}, greater than max of #{MaxNameLength} octets!") end @labels = labels @absolute = absolute end |
Instance Attribute Details
#labels ⇒ Object
Returns the value of attribute labels
75 76 77 |
# File 'lib/dnsruby/name.rb', line 75 def labels @labels end |
Class Method Details
.create(arg) ⇒ Object
–
A Name is a collection of Labels. Each label is presentation-formatted
When a Name is wire-encoded, the label array is walked, and each label is wire-encoded.
When a Name is unencoded, each label is unencoded, and added to the Name collection of labels.
When a Name is made from a string, the Name is split into Labels.
++ Creates a new Dnsruby::Name from arg
. arg
can be :
- Name
-
returns
arg
- String
-
returns a new Name
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/dnsruby/name.rb', line 43 def self.create(arg) case arg when Name return Name.new(arg.labels, arg.absolute?) when String # arg.gsub!(/\.$/o, "") if (arg==".") return Name.new([],true) end if (arg=="") return Name.new([],false) end return Name.new(split_escaped(arg), /\.\z/ =~ arg ? true : false) # return Name.new(Label.split(arg), /\.\z/ =~ arg ? true : false) when Array return Name.new(arg, /\.\z/ =~ (arg.last ? ((arg.last.kind_of?String)?arg.last : arg.last.string) : arg.last) ? true : false) else raise ArgumentError.new("cannot interpret as DNS name: #{arg.inspect}") end end |
.decode(wire) ⇒ Object
:nodoc: all
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/dnsruby/name.rb', line 266 def self.decode(wire) #:nodoc: all presentation="" length=wire.length # There must be a nice regexp to do this.. but since I failed to # find one I scan the name string until I find a '\', at that time # I start looking forward and do the magic. i=0; unpacked = wire.unpack("C*") while (i < length ) c = unpacked[i] if ( c < 33 || c > 126 ) presentation=presentation + sprintf("\\%03u" ,c) elsif ( c.chr == "\"" ) presentation=presentation + "\\\"" elsif ( c.chr == "\$") presentation=presentation + "\\\$" elsif ( c.chr == "(" ) presentation=presentation + "\\(" elsif ( c.chr == ")" ) presentation=presentation + "\\)" elsif ( c.chr == ";" ) presentation=presentation + "\\;" elsif ( c.chr == "@" ) presentation=presentation + "\\@" elsif ( c.chr == "\\" ) presentation=presentation + "\\\\" elsif ( c.chr == ".") presentation=presentation + "\\." else presentation=presentation + c.chr() end i=i+1 end return presentation # return Label.new(presentation) end |
.encode(presentation) ⇒ Object
wire,leftover=presentation2wire(leftover)
Will parse the input presentation format and return everything before
the first non-escaped "." in the first element of the return array and
all that has not been parsed yet in the 2nd argument.
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 |
# File 'lib/dnsruby/name.rb', line 312 def self.encode(presentation) #:nodoc: all presentation=presentation.to_s wire=""; length=presentation.length; i=0; while (i < length ) c=presentation.unpack("x#{i}C1") [0] if (c == 46) # ord('.') endstring = presentation[i+1, presentation.length-(i+1)] return Label.new(wire),endstring end if (c == 92) # ord'\\' # backslash found pos = i+1 # pos sets where next pattern matching should start if (presentation.index(/\G(\d\d\d)/o, pos)) wire=wire+[$1.to_i].pack("C") i=i+3 elsif(presentation.index(/\Gx([0..9a..fA..F][0..9a..fA..F])/o, pos)) wire=wire+[$1].pack("H*") i=i+3 elsif(presentation.index(/\G\./o, pos)) wire=wire+"\." i=i+1 elsif(presentation.index(/\G@/o,pos)) wire=wire+"@" i=i+1 elsif(presentation.index(/\G\(/o, pos)) wire=wire+"(" i=i+1 elsif(presentation.index(/\G\)/o, pos)) wire=wire+")" i=i+1 elsif(presentation.index(/\G\\/o, pos)) wire=wire+"\\" i+=1 end else wire = wire + [c].pack("C") end i=i+1 end return Label.new(wire) end |
.name2encodedlabels(dName) ⇒ Object
Utility function
name2labels to translate names from presentation format into an
array of "wire-format" labels.
in: dName a string with a domain name in presentation format (1035
sect 5.1)
out: an array of labels in wire format.
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/dnsruby/name.rb', line 246 def self.name2encodedlabels (dName) #:nodoc: all # Check for "\" in the name : If there, then decode properly - otherwise, cheat and split on "." if (dName.index("\\")) names=[] j=0; while (dName && dName.length > 0) names[j],dName = encode(dName) j+=1 end return names else labels = [] dName.split(".").each {|l| labels.push(Label.new(l)) } return labels end end |
.split(name) ⇒ Object
69 70 71 72 73 |
# File 'lib/dnsruby/name.rb', line 69 def self.split(name) encodedlabels = name2encodedlabels(name) labels = encodedlabels.each {|el| Name.decode(el.to_s)} return labels end |
.split_escaped(arg) ⇒ Object
:nodoc: all
64 65 66 67 |
# File 'lib/dnsruby/name.rb', line 64 def self.split_escaped(arg) #:nodoc: all encodedlabels = name2encodedlabels(arg) return encodedlabels end |
Instance Method Details
#<=>(other) ⇒ Object
135 136 137 138 139 140 141 142 |
# File 'lib/dnsruby/name.rb', line 135 def <=>(other) # return -1 if other less than us, +1 if greater than us return 0 if (canonical == other.canonical) if (canonically_before(other)) return +1 end return -1 end |
#==(other) ⇒ Object Also known as: eql?
:nodoc:
174 175 176 177 |
# File 'lib/dnsruby/name.rb', line 174 def ==(other) # :nodoc: return false if other.class != Name return @labels == other.labels && @absolute == other.absolute? end |
#[](i) ⇒ Object
:nodoc: all
210 211 212 |
# File 'lib/dnsruby/name.rb', line 210 def [](i) #:nodoc: all return @labels[i] end |
#absolute=(on) ⇒ Object
:nodoc:
109 110 111 |
# File 'lib/dnsruby/name.rb', line 109 def absolute=(on) # :nodoc: @absolute = on end |
#absolute? ⇒ Boolean
Returns true if this Name is absolute
105 106 107 |
# File 'lib/dnsruby/name.rb', line 105 def absolute? return @absolute end |
#canonical ⇒ Object
Return the canonical form of this name (RFC 4034 section 6.2)
127 128 129 130 131 132 133 |
# File 'lib/dnsruby/name.rb', line 127 def canonical # return MessageEncoder.new {|msg| msg.put_name(self, true) }.to_s end |
#canonically_before(n) ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/dnsruby/name.rb', line 144 def canonically_before(n) if (!(Name === n)) n = Name.create(n) end # Work out whether this name is canonically before the passed Name # RFC 4034 section 6.1 # For the purposes of DNS security, owner names are ordered by treating # individual labels as unsigned left-justified octet strings. The # absence of a octet sorts before a zero value octet, and uppercase # US-ASCII letters are treated as if they were lowercase US-ASCII # letters. # To compute the canonical ordering of a set of DNS names, start by # sorting the names according to their most significant (rightmost) # labels. For names in which the most significant label is identical, # continue sorting according to their next most significant label, and # so forth. # Get the list of labels for both names, and then swap them my_labels = @labels.reverse other_labels = n.labels.reverse my_labels.each_index {|i| if (!other_labels[i]) return false end next if (other_labels[i].downcase == my_labels[i].downcase) return (my_labels[i].downcase < other_labels[i].downcase) } return true end |
#downcase ⇒ Object
94 95 96 97 98 |
# File 'lib/dnsruby/name.rb', line 94 def downcase labels = [] @labels.each do |label| labels << Label.new(label.downcase) end return Name.new(labels) end |
#hash ⇒ Object
:nodoc:
198 199 200 |
# File 'lib/dnsruby/name.rb', line 198 def hash # :nodoc: return @labels.hash ^ @absolute.hash end |
#inspect ⇒ Object
:nodoc:
100 101 102 |
# File 'lib/dnsruby/name.rb', line 100 def inspect # :nodoc: "#<#{self.class}: #{self.to_s}#{@absolute ? '.' : ''}>" end |
#length ⇒ Object
:nodoc: all
206 207 208 |
# File 'lib/dnsruby/name.rb', line 206 def length #:nodoc: all return @labels.length end |
#strip_label ⇒ Object
:nodoc:
113 114 115 116 |
# File 'lib/dnsruby/name.rb', line 113 def strip_label # :nodoc: n = Name.new(self.labels()[1, self.labels.length-1], self.absolute?) return n end |
#subdomain_of?(other) ⇒ Boolean
Tests subdomain-of relation : returns true if this name
is a subdomain of +other+.
domain = Resolv::Name.create("y.z")
p Resolv::Name.create("w.x.y.z").subdomain_of?(domain) #=> true
p Resolv::Name.create("x.y.z").subdomain_of?(domain) #=> true
p Resolv::Name.create("y.z").subdomain_of?(domain) #=> false
p Resolv::Name.create("z").subdomain_of?(domain) #=> false
p Resolv::Name.create("x.y.z.").subdomain_of?(domain) #=> false
p Resolv::Name.create("w.z").subdomain_of?(domain) #=> false
190 191 192 193 194 195 196 |
# File 'lib/dnsruby/name.rb', line 190 def subdomain_of?(other) raise ArgumentError, "not a domain name: #{other.inspect}" unless Name === other return false if @absolute != other.absolute? other_len = other.length return false if @labels.length <= other_len return @labels[-other_len, other_len] == other.to_a end |
#to_a ⇒ Object
:nodoc: all
202 203 204 |
# File 'lib/dnsruby/name.rb', line 202 def to_a #:nodoc: all return @labels end |
#to_s(include_absolute = false) ⇒ Object
returns the domain name as a string.
The domain name doesn't have a trailing dot even if the name object is
absolute.
Example :
p Resolv::Name.create("x.y.z.").to_s #=> "x.y.z"
p Resolv::Name.create("x.y.z").to_s #=> "x.y.z"
224 225 226 227 228 229 230 |
# File 'lib/dnsruby/name.rb', line 224 def to_s(include_absolute=false) ret = to_str(@labels) if (@absolute && include_absolute) ret += "." end return ret end |
#to_str(labels) ⇒ Object
:nodoc: all
232 233 234 235 236 237 |
# File 'lib/dnsruby/name.rb', line 232 def to_str(labels) # :nodoc: all ls =[] labels.each {|el| ls.push(Name.decode(el.to_s))} return ls.join('.') # return @labels.collect{|l| (l.kind_of?String) ? l : l.string}.join('.') end |
#wild? ⇒ Boolean
Is this name a wildcard?
119 120 121 122 123 124 |
# File 'lib/dnsruby/name.rb', line 119 def wild? if (labels.length == 0) return false end return (labels[0].string == '*') end |