net-dns 0.6.1 → 0.7.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.
- data/.gitignore +8 -6
- data/.travis.yml +14 -0
- data/CHANGELOG.md +79 -0
- data/Gemfile +4 -0
- data/Rakefile +56 -66
- data/demo/check_soa.rb +1 -1
- data/demo/threads.rb +1 -1
- data/lib/net/dns.rb +24 -22
- data/lib/net/dns/header.rb +77 -103
- data/lib/net/dns/{names/names.rb → names.rb} +19 -20
- data/lib/net/dns/packet.rb +231 -256
- data/lib/net/dns/question.rb +11 -40
- data/lib/net/dns/resolver.rb +248 -250
- data/lib/net/dns/resolver/socks.rb +6 -6
- data/lib/net/dns/resolver/timeouts.rb +1 -1
- data/lib/net/dns/rr.rb +112 -117
- data/lib/net/dns/rr/a.rb +98 -89
- data/lib/net/dns/rr/aaaa.rb +84 -68
- data/lib/net/dns/rr/classes.rb +91 -106
- data/lib/net/dns/rr/cname.rb +64 -45
- data/lib/net/dns/rr/hinfo.rb +90 -50
- data/lib/net/dns/rr/mr.rb +61 -44
- data/lib/net/dns/rr/mx.rb +73 -48
- data/lib/net/dns/rr/ns.rb +60 -46
- data/lib/net/dns/rr/null.rb +11 -12
- data/lib/net/dns/rr/ptr.rb +47 -34
- data/lib/net/dns/rr/soa.rb +5 -6
- data/lib/net/dns/rr/srv.rb +1 -4
- data/lib/net/dns/rr/txt.rb +14 -14
- data/lib/net/dns/rr/types.rb +13 -13
- data/lib/net/dns/version.rb +8 -14
- data/net-dns.gemspec +35 -0
- data/setup.rb +3 -2
- data/test/header_test.rb +18 -18
- data/test/names_test.rb +21 -0
- data/test/packet_test.rb +38 -31
- data/test/question_test.rb +23 -24
- data/test/resolver/timeouts_test.rb +13 -13
- data/test/resolver_test.rb +28 -20
- data/test/rr/a_test.rb +70 -23
- data/test/rr/aaaa_test.rb +109 -0
- data/test/rr/classes_test.rb +61 -49
- data/test/rr/cname_test.rb +97 -0
- data/test/rr/hinfo_test.rb +117 -0
- data/test/rr/mr_test.rb +105 -0
- data/test/rr/mx_test.rb +112 -0
- data/test/rr/ns_test.rb +34 -12
- data/test/rr/types_test.rb +4 -4
- data/test/rr_test.rb +1 -1
- metadata +77 -52
- data/AUTHORS.rdoc +0 -7
- data/CHANGELOG.rdoc +0 -46
- data/VERSION.yml +0 -5
data/lib/net/dns/rr/aaaa.rb
CHANGED
@@ -1,87 +1,103 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
module Net
|
5
|
-
module DNS
|
6
|
-
|
7
|
-
class RR
|
1
|
+
module Net
|
2
|
+
module DNS
|
3
|
+
class RR
|
8
4
|
|
9
5
|
#
|
10
|
-
#
|
6
|
+
# = IPv6 Address Record (AAAA)
|
7
|
+
#
|
8
|
+
# Class for DNS IPv6 Address (AAAA) resource records.
|
11
9
|
#
|
12
10
|
class AAAA < RR
|
13
|
-
attr_reader :address
|
14
11
|
|
15
|
-
#
|
16
|
-
#
|
12
|
+
# Gets the current IPv6 address for this record.
|
13
|
+
#
|
14
|
+
# Returns an instance of IPAddr.
|
15
|
+
def address
|
16
|
+
@address
|
17
|
+
end
|
18
|
+
|
19
|
+
# Assigns a new IPv6 address to this record, which can be in the
|
20
|
+
# form of a <tt>String</tt> or an <tt>IPAddr</tt> object.
|
17
21
|
#
|
18
|
-
#
|
19
|
-
# a.address = IPAddr.new("::1")
|
22
|
+
# Examples
|
20
23
|
#
|
21
|
-
|
22
|
-
|
24
|
+
# a.address = "192.168.0.1"
|
25
|
+
# a.address = IPAddr.new("10.0.0.1")
|
26
|
+
#
|
27
|
+
# Returns the new allocated instance of IPAddr.
|
28
|
+
def address=(string_or_ipaddr)
|
29
|
+
@address = check_address(string_or_ipaddr)
|
23
30
|
build_pack
|
24
|
-
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def check_address(addr)
|
29
|
-
address = ""
|
30
|
-
case addr
|
31
|
-
when String
|
32
|
-
address = IPAddr.new addr
|
33
|
-
when IPAddr
|
34
|
-
address = addr
|
35
|
-
else
|
36
|
-
raise ArgumentError, "Unknown address type: #{addr.inspect}"
|
37
|
-
end
|
38
|
-
raise ArgumentError, "Must specify an IPv6 address" unless address.ipv6?
|
39
|
-
address
|
40
|
-
rescue ArgumentError
|
41
|
-
raise ArgumentError, "Invalid address #{addr.inspect}"
|
42
|
-
end
|
43
|
-
|
44
|
-
def build_pack
|
45
|
-
@address_pack = @address.hton
|
46
|
-
@rdlength = @address_pack.size
|
47
|
-
end
|
48
|
-
|
49
|
-
def get_data
|
50
|
-
@address_pack
|
31
|
+
@address
|
51
32
|
end
|
52
33
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
def
|
58
|
-
|
59
|
-
@address = check_address args[:address]
|
60
|
-
else
|
61
|
-
raise ArgumentError, ":address field is mandatory but missing"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def subclass_new_from_string(str)
|
66
|
-
@address = check_address(str)
|
67
|
-
end
|
68
|
-
|
69
|
-
def subclass_new_from_binary(data,offset)
|
70
|
-
arr = data.unpack("@#{offset} n8")
|
71
|
-
@address = IPAddr.new sprintf("%x:%x:%x:%x:%x:%x:%x:%x",*arr)
|
72
|
-
return offset + 16
|
34
|
+
# Gets the standardized value for this record,
|
35
|
+
# represented by the value of <tt>address</tt>.
|
36
|
+
#
|
37
|
+
# Returns a String.
|
38
|
+
def value
|
39
|
+
address.to_s
|
73
40
|
end
|
74
|
-
|
41
|
+
|
42
|
+
|
75
43
|
private
|
76
|
-
|
44
|
+
|
45
|
+
def subclass_new_from_hash(options)
|
46
|
+
if options.has_key?(:address)
|
47
|
+
@address = check_address(options[:address])
|
48
|
+
else
|
49
|
+
raise ArgumentError, ":address field is mandatory"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def subclass_new_from_string(str)
|
54
|
+
@address = check_address(str)
|
55
|
+
end
|
56
|
+
|
57
|
+
def subclass_new_from_binary(data, offset)
|
58
|
+
tokens = data.unpack("@#{offset} n8")
|
59
|
+
@address = IPAddr.new(sprintf("%x:%x:%x:%x:%x:%x:%x:%x", *tokens))
|
60
|
+
offset + 16
|
61
|
+
end
|
62
|
+
|
63
|
+
|
77
64
|
def set_type
|
78
65
|
@type = Net::DNS::RR::Types.new("AAAA")
|
79
66
|
end
|
80
|
-
|
67
|
+
|
68
|
+
def get_inspect
|
69
|
+
value
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def check_address(input)
|
74
|
+
address = case input
|
75
|
+
when IPAddr
|
76
|
+
input
|
77
|
+
when String
|
78
|
+
IPAddr.new(input)
|
79
|
+
else
|
80
|
+
raise ArgumentError, "Invalid IP address `#{input}'"
|
81
|
+
end
|
82
|
+
|
83
|
+
if !address.ipv6?
|
84
|
+
raise(ArgumentError, "Must specify an IPv6 address")
|
85
|
+
end
|
86
|
+
|
87
|
+
address
|
88
|
+
end
|
89
|
+
|
90
|
+
def build_pack
|
91
|
+
@address_pack = @address.hton
|
92
|
+
@rdlength = @address_pack.size
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_data
|
96
|
+
@address_pack
|
97
|
+
end
|
98
|
+
|
81
99
|
end
|
82
|
-
|
100
|
+
|
83
101
|
end
|
84
102
|
end
|
85
103
|
end
|
86
|
-
|
87
|
-
|
data/lib/net/dns/rr/classes.rb
CHANGED
@@ -1,148 +1,133 @@
|
|
1
|
-
module Net
|
2
|
-
module DNS
|
3
|
-
|
1
|
+
module Net
|
2
|
+
module DNS
|
3
|
+
|
4
4
|
class RR
|
5
|
-
|
5
|
+
|
6
6
|
#
|
7
|
-
#
|
7
|
+
# = Net::DNS::Classes
|
8
|
+
#
|
9
|
+
# This is an auxiliary class to handle <tt>Net::DNS::RR</tt>
|
10
|
+
# class field in a DNS packet.
|
8
11
|
#
|
9
12
|
class Classes
|
10
|
-
|
11
|
-
#
|
12
|
-
# respective id number
|
13
|
-
|
13
|
+
|
14
|
+
# Hash with the values of each RR class stored with the
|
15
|
+
# respective id number.
|
16
|
+
CLASSES = {
|
14
17
|
'IN' => 1, # RFC 1035
|
15
18
|
'CH' => 3, # RFC 1035
|
16
19
|
'HS' => 4, # RFC 1035
|
17
20
|
'NONE' => 254, # RFC 2136
|
18
21
|
'ANY' => 255, # RFC 1035
|
19
22
|
}
|
20
|
-
|
21
|
-
# The default value when class is nil in Resource Records
|
22
|
-
@@default = Classes["IN"]
|
23
23
|
|
24
|
-
#
|
25
|
-
|
26
|
-
def self.default=(str)
|
27
|
-
if Classes.has_key? str
|
28
|
-
@@default = Classes[str]
|
29
|
-
else
|
30
|
-
raise ClassArgumentError, "Unknown class #{str}"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# Checks whether +cls+ is a valid RR class.
|
35
|
-
def self.valid?(cls)
|
36
|
-
case cls
|
37
|
-
when String
|
38
|
-
return Classes.has_key?(cls)
|
39
|
-
when Fixnum
|
40
|
-
return Classes.invert.has_key?(cls)
|
41
|
-
else
|
42
|
-
raise ClassArgumentError, "Wrong cls class: #{cls.class}"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Returns the class in string format, as "IN" or "CH",
|
47
|
-
# given the numeric value
|
48
|
-
def self.to_str(cls)
|
49
|
-
case cls
|
50
|
-
when Fixnum
|
51
|
-
if Classes.invert.has_key? cls
|
52
|
-
return Classes.invert[cls]
|
53
|
-
else
|
54
|
-
raise ClassArgumentError, "Unknown class number #{cls}"
|
55
|
-
end
|
56
|
-
else
|
57
|
-
raise ClassArgumentError, "Wrong cls class: #{cls.class}"
|
58
|
-
end
|
59
|
-
end
|
24
|
+
# The default value when class is nil in Resource Records
|
25
|
+
@@default = CLASSES["IN"]
|
60
26
|
|
61
|
-
# Gives in output the keys from the +Classes+ hash
|
62
|
-
# in a format suited for regexps
|
63
|
-
def self.regexp
|
64
|
-
Classes.keys.sort.join("|")
|
65
|
-
end
|
66
27
|
|
67
28
|
# Creates a new object representing an RR class. Performs some
|
68
29
|
# checks on the argument validity too. Il +cls+ is +nil+, the
|
69
30
|
# default value is +ANY+ or the one set with Classes.default=
|
70
31
|
def initialize(cls)
|
71
32
|
case cls
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
when nil
|
79
|
-
# default type, control with Classes.default=
|
80
|
-
@str = Classes.invert[@@default]
|
81
|
-
@num = @@default
|
82
|
-
else
|
83
|
-
raise ClassArgumentError, "Wrong cls class: #{cls.class}"
|
33
|
+
when String
|
34
|
+
initialize_from_str(cls)
|
35
|
+
when Fixnum
|
36
|
+
initialize_from_num(cls)
|
37
|
+
when nil
|
38
|
+
initialize_from_num(@@default)
|
84
39
|
end
|
85
|
-
end
|
86
40
|
|
87
|
-
|
88
|
-
|
89
|
-
def new_from_string(cls)
|
90
|
-
case cls
|
91
|
-
when /^CLASS\\d+/
|
92
|
-
# TODO!!!
|
93
|
-
else
|
94
|
-
# String with name of class
|
95
|
-
if Classes.has_key? cls
|
96
|
-
@str = cls
|
97
|
-
@num = Classes[cls]
|
98
|
-
else
|
99
|
-
raise ClassesArgumentError, "Unknown cls #{cls}"
|
100
|
-
end
|
41
|
+
if @str.nil? || @num.nil?
|
42
|
+
raise ArgumentError, "Unable to create a `Classes' from `#{cls}'"
|
101
43
|
end
|
102
44
|
end
|
103
45
|
|
104
|
-
#
|
105
|
-
# *PRIVATE* method
|
106
|
-
def new_from_num(cls)
|
107
|
-
if Classes.invert.has_key? cls
|
108
|
-
@num = cls
|
109
|
-
@str = Classes.invert[cls]
|
110
|
-
else
|
111
|
-
raise ClassesArgumentError, "Unkown cls number #{cls}"
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# Returns the class in number format
|
46
|
+
# Returns the class in number format
|
116
47
|
# (default for normal use)
|
48
|
+
#
|
49
|
+
# FIXME: inspect must return a String.
|
50
|
+
#
|
117
51
|
def inspect
|
118
52
|
@num
|
119
53
|
end
|
120
54
|
|
121
55
|
# Returns the class in string format,
|
122
|
-
#
|
56
|
+
# ex. "IN" or "CH" or such a string.
|
123
57
|
def to_s
|
124
|
-
@str
|
58
|
+
@str.to_s
|
125
59
|
end
|
126
|
-
|
60
|
+
|
127
61
|
# Returns the class in numeric format,
|
128
|
-
# usable by the pack methods for data transfers
|
62
|
+
# usable by the pack methods for data transfers.
|
129
63
|
def to_i
|
130
64
|
@num.to_i
|
131
65
|
end
|
132
66
|
|
133
67
|
|
134
|
-
|
135
|
-
|
136
|
-
|
68
|
+
|
69
|
+
# Be able to control the default class to assign when
|
70
|
+
# cls argument is +nil+. Default to +IN+
|
71
|
+
def self.default=(str)
|
72
|
+
if CLASSES[str]
|
73
|
+
@@default = CLASSES[str]
|
74
|
+
else
|
75
|
+
raise ArgumentError, "Unknown class `#{str}'"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns whether <tt>cls</tt> is a valid RR class.
|
80
|
+
#
|
81
|
+
# Net::DNS::RR::Classes.valid?("IN")
|
82
|
+
# # => true
|
83
|
+
# Net::DNS::RR::Classes.valid?(1)
|
84
|
+
# # => true
|
85
|
+
# Net::DNS::RR::Classes.valid?("Q")
|
86
|
+
# # => false
|
87
|
+
# Net::DNS::RR::Classes.valid?(256)
|
88
|
+
# # => false
|
89
|
+
# Net::DNS::RR::Classes.valid?(Hash.new)
|
90
|
+
# # => ArgumentError
|
91
|
+
#
|
92
|
+
# FIXME: valid? should never raise.
|
93
|
+
#
|
94
|
+
# ==== Raises
|
95
|
+
# ArgumentError:: if <tt>cls</tt> isn't either a String or a Fixnum
|
96
|
+
#
|
97
|
+
def self.valid?(cls)
|
98
|
+
case cls
|
99
|
+
when String
|
100
|
+
CLASSES.has_key?(cls)
|
101
|
+
when Fixnum
|
102
|
+
CLASSES.invert.has_key?(cls)
|
103
|
+
else
|
104
|
+
raise ArgumentError, "Wrong cls class: #{cls.class}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Gives in output the keys from the +Classes+ hash
|
109
|
+
# in a format suited for regexps
|
110
|
+
def self.regexp
|
111
|
+
CLASSES.keys.sort.join("|")
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
# Initialize a new instance from a Class name.
|
118
|
+
def initialize_from_str(str)
|
119
|
+
key = str.to_s.upcase
|
120
|
+
@num, @str = CLASSES[key], key
|
137
121
|
end
|
138
122
|
|
139
|
-
|
123
|
+
# Initialize a new instance from the Class value.
|
124
|
+
def initialize_from_num(num)
|
125
|
+
key = num.to_i
|
126
|
+
@num, @str = key, CLASSES.invert[key]
|
127
|
+
end
|
140
128
|
|
141
|
-
end
|
142
|
-
|
143
|
-
end # class RR
|
144
|
-
end # module DNS
|
145
|
-
end # module Net
|
129
|
+
end
|
146
130
|
|
147
|
-
|
131
|
+
end
|
132
|
+
end
|
148
133
|
end
|
data/lib/net/dns/rr/cname.rb
CHANGED
@@ -1,63 +1,82 @@
|
|
1
|
-
module Net
|
1
|
+
module Net # :nodoc:
|
2
2
|
module DNS
|
3
|
-
|
4
3
|
class RR
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
|
4
|
+
|
5
|
+
#
|
6
|
+
# = Canonical Name Record (CNAME)
|
7
|
+
#
|
8
|
+
# Class for DNS CNAME resource records.
|
9
|
+
#
|
10
|
+
# A CNAME record maps an alias or nickname to the real or Canonical name
|
11
|
+
# which may lie outside the current zone.
|
12
|
+
# Canonical means expected or real name.
|
13
|
+
#
|
9
14
|
class CNAME < RR
|
10
|
-
attr_reader :cname
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
name
|
16
|
+
# Gets the canonical name value.
|
17
|
+
#
|
18
|
+
# Returns a String.
|
19
|
+
def cname
|
20
|
+
@cname
|
19
21
|
end
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
# Gets the standardized value for this record,
|
24
|
+
# represented by the value of <tt>cname</tt>.
|
25
|
+
#
|
26
|
+
# Returns a String.
|
27
|
+
def value
|
28
|
+
cname.to_s
|
24
29
|
end
|
25
30
|
|
26
|
-
def get_data
|
27
|
-
@cname_pack
|
28
|
-
end
|
29
31
|
|
30
|
-
|
31
|
-
"#@cname"
|
32
|
-
end
|
32
|
+
private
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
def subclass_new_from_hash(options)
|
35
|
+
if options.has_key?(:cname)
|
36
|
+
@cname = check_name(options[:cname])
|
37
|
+
else
|
38
|
+
raise ArgumentError, ":cname field is mandatory"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def subclass_new_from_string(str)
|
43
|
+
@cname = check_name(str)
|
44
|
+
end
|
45
|
+
|
46
|
+
def subclass_new_from_binary(data, offset)
|
47
|
+
@cname, offset = dn_expand(data, offset)
|
48
|
+
offset
|
39
49
|
end
|
40
|
-
end
|
41
50
|
|
42
|
-
def subclass_new_from_string(str)
|
43
|
-
@cname = check_name(str)
|
44
|
-
end
|
45
51
|
|
46
|
-
def subclass_new_from_binary(data,offset)
|
47
|
-
@cname,offset = dn_expand(data,offset)
|
48
|
-
return offset
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
52
|
def set_type
|
54
53
|
@type = Net::DNS::RR::Types.new("CNAME")
|
55
54
|
end
|
56
|
-
|
57
|
-
end # class CNAME
|
58
|
-
|
59
|
-
end # class RR
|
60
|
-
end # module DNS
|
61
|
-
end # module Net
|
62
55
|
|
56
|
+
def get_inspect
|
57
|
+
value
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def check_name(input)
|
62
|
+
name = input.to_s
|
63
|
+
unless name =~ /(\w\.?)+\s*$/ and name =~ /[a-zA-Z]/
|
64
|
+
raise ArgumentError, "Invalid Canonical Name `#{name}'"
|
65
|
+
end
|
66
|
+
name
|
67
|
+
end
|
68
|
+
|
69
|
+
def build_pack
|
70
|
+
@cname_pack = pack_name(@cname)
|
71
|
+
@rdlength = @cname_pack.size
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_data
|
75
|
+
@cname_pack
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
63
79
|
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|