Class: ReDNS::Name

Inherits:
Fragment show all
Defined in:
lib/redns/name.rb

Constant Summary collapse

POINTER_CHAIN_LIMIT =

Constants ============================================================

64

Instance Attribute Summary

Attributes inherited from Fragment

#attributes

Instance Method Summary collapse

Methods inherited from Fragment

attribute

Methods included from Support

#addr_to_arpa, #bind_all_addr, #default_nameservers, #default_resolver_address, #dns_port, #inet_aton, #inet_ntoa, #io_nonblock, #io_nonblock?, #io_set_nonblock, #is_ip?

Constructor Details

#initialize(contents = nil) ⇒ Name

Instance Methods =====================================================



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/redns/name.rb', line 12

def initialize(contents = nil)
  case (contents)
  when ReDNS::Buffer
    # Ensure that this String subclass is handled using the default
    # method, not intercepted and treated as an actual String
    super(contents)
  when String
    super(:name => contents)
    
    unless (ReDNS::Support.is_ip?(name) or self.name.match(/\.$/))
      self.name += '.'
    end
  else
    super(contents)
  end
end

Instance Method Details

#deserialize(buffer) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/redns/name.rb', line 55

def deserialize(buffer)
	self.name = ''
	
	return_to_offset = nil
	pointer_count = 0

   while (c = buffer.unpack('C')[0])
     if (c & 0xC0 == 0xC0)
       # This is part of a pointer to another section, so advance to that
       # point and read from there, but preserve the position where the
       # pointer was found to leave the buffer in that final state.

       if (additional_offset = buffer.unpack('C')[0])
         pointer = (c & 0x3F << 8) | additional_offset

         return_to_offset ||= buffer.offset
         buffer.rewind
         buffer.advance(pointer)
         
         pointer_count += 1
         
         if (pointer_count > POINTER_CHAIN_LIMIT)
           # Encountered too many pointers, probably a sign of a circular
           # reference or a badly constructed response. Ignore.
           break
         end
       else
         # The buffer may have prematurely run dry, in which case the only
         # option left is to abandon further processing.
         break
       end
     elsif (c == 0)
       break
     else
       if (read = buffer.read(c))
         name << read
         name << '.'
       else
         break
       end
     end
   end
   
   if (return_to_offset)
     buffer.rewind
     buffer.advance(return_to_offset)
   end
   
   self
end

#empty?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/redns/name.rb', line 41

def empty?
	name == '.'
end

#lengthObject



37
38
39
# File 'lib/redns/name.rb', line 37

def length
	to_s.length
end

#serialize(buffer = ReDNS::Buffer.new) ⇒ Object



45
46
47
48
49
50
51
52
53
# File 'lib/redns/name.rb', line 45

def serialize(buffer = ReDNS::Buffer.new)
	buffer.append(
	  self.name.split(/\./).collect { |l| [ l.length, l ].pack("ca*") }.join('')
	)

	buffer.append("\0")
	
	buffer
end

#to_aObject



33
34
35
# File 'lib/redns/name.rb', line 33

def to_a
	[ self.name ]
end

#to_sObject



29
30
31
# File 'lib/redns/name.rb', line 29

def to_s
  self.name
end