Class: Dnsruby::Name
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.
-
.punycode(d) ⇒ String
Convert IDN domain from Unicode UTF-8 to ASCII punycode.
- .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
95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/dnsruby/name.rb', line 95 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.
91 92 93 |
# File 'lib/dnsruby/name.rb', line 91 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
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/dnsruby/name.rb', line 44 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 arg = punycode(arg) 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
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 |
# File 'lib/dnsruby/name.rb', line 282 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.
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 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
# File 'lib/dnsruby/name.rb', line 328 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(\h\h)/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.
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/dnsruby/name.rb', line 262 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 |
.punycode(d) ⇒ String
Convert IDN domain from Unicode UTF-8 to ASCII punycode
72 73 74 75 76 77 78 |
# File 'lib/dnsruby/name.rb', line 72 def self.punycode(d) begin return SimpleIDN.to_ascii(d) rescue return d end end |
.split(name) ⇒ Object
85 86 87 88 89 |
# File 'lib/dnsruby/name.rb', line 85 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
80 81 82 83 |
# File 'lib/dnsruby/name.rb', line 80 def self.split_escaped(arg) #:nodoc: all encodedlabels = name2encodedlabels(arg) return encodedlabels end |
Instance Method Details
#<=>(other) ⇒ Object
151 152 153 154 155 156 157 158 |
# File 'lib/dnsruby/name.rb', line 151 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:
190 191 192 193 |
# File 'lib/dnsruby/name.rb', line 190 def ==(other) # :nodoc: return false if other.class != Name return @labels == other.labels && @absolute == other.absolute? end |
#[](i) ⇒ Object
:nodoc: all
226 227 228 |
# File 'lib/dnsruby/name.rb', line 226 def [](i) #:nodoc: all return @labels[i] end |
#absolute=(on) ⇒ Object
:nodoc:
125 126 127 |
# File 'lib/dnsruby/name.rb', line 125 def absolute=(on) # :nodoc: @absolute = on end |
#absolute? ⇒ Boolean
Returns true if this Name is absolute
121 122 123 |
# File 'lib/dnsruby/name.rb', line 121 def absolute? return @absolute end |
#canonical ⇒ Object
Return the canonical form of this name (RFC 4034 section 6.2)
143 144 145 146 147 148 149 |
# File 'lib/dnsruby/name.rb', line 143 def canonical # return MessageEncoder.new {|msg| msg.put_name(self, true) }.to_s end |
#canonically_before(n) ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/dnsruby/name.rb', line 160 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
110 111 112 113 114 |
# File 'lib/dnsruby/name.rb', line 110 def downcase labels = [] @labels.each do |label| labels << Label.new(label.downcase) end return Name.new(labels) end |
#hash ⇒ Object
:nodoc:
214 215 216 |
# File 'lib/dnsruby/name.rb', line 214 def hash # :nodoc: return @labels.hash ^ @absolute.hash end |
#inspect ⇒ Object
:nodoc:
116 117 118 |
# File 'lib/dnsruby/name.rb', line 116 def inspect # :nodoc: "#<#{self.class}: #{self.to_s}#{@absolute ? '.' : ''}>" end |
#length ⇒ Object
:nodoc: all
222 223 224 |
# File 'lib/dnsruby/name.rb', line 222 def length #:nodoc: all return @labels.length end |
#strip_label ⇒ Object
:nodoc:
129 130 131 132 |
# File 'lib/dnsruby/name.rb', line 129 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
206 207 208 209 210 211 212 |
# File 'lib/dnsruby/name.rb', line 206 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
218 219 220 |
# File 'lib/dnsruby/name.rb', line 218 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"
240 241 242 243 244 245 246 |
# File 'lib/dnsruby/name.rb', line 240 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
248 249 250 251 252 253 |
# File 'lib/dnsruby/name.rb', line 248 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?
135 136 137 138 139 140 |
# File 'lib/dnsruby/name.rb', line 135 def wild? if (labels.length == 0) return false end return (labels[0].string == '*') end |