net-dns 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/.gitignore +1 -1
- data/.rspec +1 -0
- data/.rubocop.yml +3 -0
- data/.rubocop_defaults.yml +364 -0
- data/.rubocop_todo.yml +207 -0
- data/.travis.yml +9 -16
- data/CHANGELOG.md +12 -1
- data/Gemfile +6 -2
- data/LICENSE.txt +56 -0
- data/README.md +94 -77
- data/Rakefile +23 -56
- data/bin/console +14 -0
- data/demo/check_soa.rb +27 -38
- data/demo/threads.rb +3 -7
- data/lib/net/dns.rb +4 -11
- data/lib/net/dns/core_ext.rb +8 -15
- data/lib/net/dns/header.rb +58 -66
- data/lib/net/dns/names.rb +25 -23
- data/lib/net/dns/packet.rb +136 -139
- data/lib/net/dns/question.rb +36 -39
- data/lib/net/dns/resolver.rb +103 -113
- data/lib/net/dns/resolver/socks.rb +45 -51
- data/lib/net/dns/resolver/timeouts.rb +17 -26
- data/lib/net/dns/rr.rb +107 -117
- data/lib/net/dns/rr/a.rb +46 -55
- data/lib/net/dns/rr/aaaa.rb +40 -49
- data/lib/net/dns/rr/classes.rb +26 -29
- data/lib/net/dns/rr/cname.rb +33 -41
- data/lib/net/dns/rr/hinfo.rb +44 -56
- data/lib/net/dns/rr/mr.rb +33 -42
- data/lib/net/dns/rr/mx.rb +37 -47
- data/lib/net/dns/rr/ns.rb +33 -41
- data/lib/net/dns/rr/null.rb +8 -11
- data/lib/net/dns/rr/ptr.rb +14 -20
- data/lib/net/dns/rr/soa.rb +27 -30
- data/lib/net/dns/rr/srv.rb +13 -17
- data/lib/net/dns/rr/txt.rb +8 -11
- data/lib/net/dns/rr/types.rb +97 -99
- data/lib/net/dns/version.rb +5 -13
- data/net-dns.gemspec +17 -29
- data/{fixtures → spec/fixtures}/resolv.conf +0 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/unit/resolver/dns_timeout_spec.rb +36 -0
- data/spec/unit/resolver/tcp_timeout_spec.rb +46 -0
- data/spec/unit/resolver/udp_timeout_spec.rb +46 -0
- data/test/test_helper.rb +12 -3
- data/test/{header_test.rb → unit/header_test.rb} +43 -46
- data/test/{names_test.rb → unit/names_test.rb} +1 -1
- data/test/{packet_test.rb → unit/packet_test.rb} +3 -5
- data/test/{question_test.rb → unit/question_test.rb} +3 -5
- data/test/{resolver_test.rb → unit/resolver_test.rb} +10 -13
- data/test/{rr → unit/rr}/a_test.rb +10 -17
- data/test/{rr → unit/rr}/aaaa_test.rb +7 -14
- data/test/{rr → unit/rr}/classes_test.rb +14 -16
- data/test/{rr → unit/rr}/cname_test.rb +7 -14
- data/test/{rr → unit/rr}/hinfo_test.rb +16 -22
- data/test/{rr → unit/rr}/mr_test.rb +12 -18
- data/test/{rr → unit/rr}/mx_test.rb +18 -24
- data/test/{rr → unit/rr}/ns_test.rb +10 -16
- data/test/{rr → unit/rr}/types_test.rb +10 -8
- data/test/{rr_test.rb → unit/rr_test.rb} +33 -37
- metadata +77 -49
- data/test/resolver/timeouts_test.rb +0 -109
data/lib/net/dns/rr/a.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Net
|
2
2
|
module DNS
|
3
3
|
class RR
|
4
|
-
|
5
4
|
#
|
6
5
|
# = IPv4 Address Record (A)
|
7
6
|
#
|
@@ -23,13 +22,10 @@ module Net
|
|
23
22
|
# without any embedded space (e.g. "10.2.0.52" or "192.0.5.6").
|
24
23
|
#
|
25
24
|
class A < RR
|
26
|
-
|
27
25
|
# Gets the current IPv4 address for this record.
|
28
26
|
#
|
29
27
|
# Returns an instance of IPAddr.
|
30
|
-
|
31
|
-
@address
|
32
|
-
end
|
28
|
+
attr_reader :address
|
33
29
|
|
34
30
|
# Assigns a new IPv4 address to this record, which can be in the
|
35
31
|
# form of a <tt>String</tt> or an <tt>IPAddr</tt> object.
|
@@ -54,71 +50,66 @@ module Net
|
|
54
50
|
address.to_s
|
55
51
|
end
|
56
52
|
|
57
|
-
|
58
53
|
private
|
59
54
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
55
|
+
def subclass_new_from_hash(options)
|
56
|
+
if options.key?(:address)
|
57
|
+
@address = check_address(options[:address])
|
58
|
+
elsif options.key?(:rdata)
|
59
|
+
@address = check_address(options[:rdata])
|
60
|
+
else
|
61
|
+
raise ArgumentError, ":address or :rdata field is mandatory"
|
68
62
|
end
|
63
|
+
end
|
69
64
|
|
70
|
-
|
71
|
-
|
72
|
-
|
65
|
+
def subclass_new_from_string(str)
|
66
|
+
@address = check_address(str)
|
67
|
+
end
|
73
68
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
69
|
+
def subclass_new_from_binary(data, offset)
|
70
|
+
a, b, c, d = data.unpack("@#{offset} CCCC")
|
71
|
+
@address = IPAddr.new("#{a}.#{b}.#{c}.#{d}")
|
72
|
+
offset + 4
|
73
|
+
end
|
79
74
|
|
75
|
+
def set_type
|
76
|
+
@type = Net::DNS::RR::Types.new("A")
|
77
|
+
end
|
80
78
|
|
81
|
-
|
82
|
-
|
83
|
-
|
79
|
+
def get_inspect
|
80
|
+
value
|
81
|
+
end
|
84
82
|
|
85
|
-
|
86
|
-
|
83
|
+
def check_address(input)
|
84
|
+
address = case input
|
85
|
+
when IPAddr
|
86
|
+
input
|
87
|
+
when Integer # Address in numeric form
|
88
|
+
tmp = [(input >> 24), (input >> 16) & 0xFF, (input >> 8) & 0xFF, input & 0xFF]
|
89
|
+
tmp = tmp.collect(&:to_s).join(".")
|
90
|
+
IPAddr.new(tmp)
|
91
|
+
when String
|
92
|
+
IPAddr.new(input)
|
93
|
+
else
|
94
|
+
raise ArgumentError, "Invalid IP address `#{input}'"
|
87
95
|
end
|
88
96
|
|
89
|
-
|
90
|
-
|
91
|
-
address = case input
|
92
|
-
when IPAddr
|
93
|
-
input
|
94
|
-
when Integer # Address in numeric form
|
95
|
-
tmp = [(input >> 24), (input >> 16) & 0xFF, (input >> 8) & 0xFF, input & 0xFF]
|
96
|
-
tmp = tmp.collect { |x| x.to_s }.join(".")
|
97
|
-
IPAddr.new(tmp)
|
98
|
-
when String
|
99
|
-
IPAddr.new(input)
|
100
|
-
else
|
101
|
-
raise ArgumentError, "Invalid IP address `#{input}'"
|
102
|
-
end
|
103
|
-
|
104
|
-
if !address.ipv4?
|
105
|
-
raise(ArgumentError, "Must specify an IPv4 address")
|
106
|
-
end
|
107
|
-
|
108
|
-
address
|
97
|
+
unless address.ipv4?
|
98
|
+
raise(ArgumentError, "Must specify an IPv4 address")
|
109
99
|
end
|
110
100
|
|
111
|
-
|
112
|
-
|
113
|
-
@rdlength = @address_pack.size
|
114
|
-
end
|
101
|
+
address
|
102
|
+
end
|
115
103
|
|
116
|
-
|
117
|
-
|
118
|
-
|
104
|
+
def build_pack
|
105
|
+
@address_pack = @address.hton
|
106
|
+
@rdlength = @address_pack.size
|
107
|
+
end
|
119
108
|
|
109
|
+
def get_data
|
110
|
+
@address_pack
|
111
|
+
end
|
120
112
|
end
|
121
|
-
|
122
113
|
end
|
123
114
|
end
|
124
115
|
end
|
data/lib/net/dns/rr/aaaa.rb
CHANGED
@@ -1,20 +1,16 @@
|
|
1
1
|
module Net
|
2
2
|
module DNS
|
3
3
|
class RR
|
4
|
-
|
5
4
|
#
|
6
5
|
# = IPv6 Address Record (AAAA)
|
7
6
|
#
|
8
7
|
# Class for DNS IPv6 Address (AAAA) resource records.
|
9
8
|
#
|
10
9
|
class AAAA < RR
|
11
|
-
|
12
10
|
# Gets the current IPv6 address for this record.
|
13
11
|
#
|
14
12
|
# Returns an instance of IPAddr.
|
15
|
-
|
16
|
-
@address
|
17
|
-
end
|
13
|
+
attr_reader :address
|
18
14
|
|
19
15
|
# Assigns a new IPv6 address to this record, which can be in the
|
20
16
|
# form of a <tt>String</tt> or an <tt>IPAddr</tt> object.
|
@@ -39,65 +35,60 @@ module Net
|
|
39
35
|
address.to_s
|
40
36
|
end
|
41
37
|
|
42
|
-
|
43
38
|
private
|
44
39
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
40
|
+
def subclass_new_from_hash(options)
|
41
|
+
if options.key?(:address)
|
42
|
+
@address = check_address(options[:address])
|
43
|
+
else
|
44
|
+
raise ArgumentError, ":address field is mandatory"
|
51
45
|
end
|
46
|
+
end
|
52
47
|
|
53
|
-
|
54
|
-
|
55
|
-
|
48
|
+
def subclass_new_from_string(str)
|
49
|
+
@address = check_address(str)
|
50
|
+
end
|
56
51
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
52
|
+
def subclass_new_from_binary(data, offset)
|
53
|
+
tokens = data.unpack("@#{offset} n8")
|
54
|
+
@address = IPAddr.new(format("%x:%x:%x:%x:%x:%x:%x:%x", *tokens))
|
55
|
+
offset + 16
|
56
|
+
end
|
62
57
|
|
58
|
+
def set_type
|
59
|
+
@type = Net::DNS::RR::Types.new("AAAA")
|
60
|
+
end
|
63
61
|
|
64
|
-
|
65
|
-
|
66
|
-
|
62
|
+
def get_inspect
|
63
|
+
value
|
64
|
+
end
|
67
65
|
|
68
|
-
|
69
|
-
|
66
|
+
def check_address(input)
|
67
|
+
address = case input
|
68
|
+
when IPAddr
|
69
|
+
input
|
70
|
+
when String
|
71
|
+
IPAddr.new(input)
|
72
|
+
else
|
73
|
+
raise ArgumentError, "Invalid IP address `#{input}'"
|
70
74
|
end
|
71
75
|
|
72
|
-
|
73
|
-
|
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
|
76
|
+
unless address.ipv6?
|
77
|
+
raise(ArgumentError, "Must specify an IPv6 address")
|
88
78
|
end
|
89
79
|
|
90
|
-
|
91
|
-
|
92
|
-
@rdlength = @address_pack.size
|
93
|
-
end
|
80
|
+
address
|
81
|
+
end
|
94
82
|
|
95
|
-
|
96
|
-
|
97
|
-
|
83
|
+
def build_pack
|
84
|
+
@address_pack = @address.hton
|
85
|
+
@rdlength = @address_pack.size
|
86
|
+
end
|
98
87
|
|
88
|
+
def get_data
|
89
|
+
@address_pack
|
90
|
+
end
|
99
91
|
end
|
100
|
-
|
101
92
|
end
|
102
93
|
end
|
103
94
|
end
|
data/lib/net/dns/rr/classes.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Net
|
2
2
|
module DNS
|
3
|
-
|
4
3
|
class RR
|
5
|
-
|
6
4
|
#
|
7
5
|
# = Net::DNS::Classes
|
8
6
|
#
|
@@ -10,32 +8,30 @@ module Net
|
|
10
8
|
# class field in a DNS packet.
|
11
9
|
#
|
12
10
|
class Classes
|
13
|
-
|
14
11
|
# Hash with the values of each RR class stored with the
|
15
12
|
# respective id number.
|
16
13
|
CLASSES = {
|
17
|
-
'IN'
|
18
|
-
'CH'
|
19
|
-
'HS'
|
20
|
-
'NONE'
|
21
|
-
'ANY'
|
22
|
-
}
|
14
|
+
'IN' => 1, # RFC 1035
|
15
|
+
'CH' => 3, # RFC 1035
|
16
|
+
'HS' => 4, # RFC 1035
|
17
|
+
'NONE' => 254, # RFC 2136
|
18
|
+
'ANY' => 255, # RFC 1035
|
19
|
+
}.freeze
|
23
20
|
|
24
21
|
# The default value when class is nil in Resource Records
|
25
22
|
@@default = CLASSES["IN"]
|
26
23
|
|
27
|
-
|
28
24
|
# Creates a new object representing an RR class. Performs some
|
29
25
|
# checks on the argument validity too. Il +cls+ is +nil+, the
|
30
26
|
# default value is +ANY+ or the one set with Classes.default=
|
31
27
|
def initialize(cls)
|
32
28
|
case cls
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
29
|
+
when String
|
30
|
+
initialize_from_str(cls)
|
31
|
+
when Integer
|
32
|
+
initialize_from_num(cls)
|
33
|
+
when nil
|
34
|
+
initialize_from_num(@@default)
|
39
35
|
end
|
40
36
|
|
41
37
|
if @str.nil? || @num.nil?
|
@@ -64,7 +60,9 @@ module Net
|
|
64
60
|
@num.to_i
|
65
61
|
end
|
66
62
|
|
67
|
-
|
63
|
+
def self.default
|
64
|
+
@@default
|
65
|
+
end
|
68
66
|
|
69
67
|
# Be able to control the default class to assign when
|
70
68
|
# cls argument is +nil+. Default to +IN+
|
@@ -96,12 +94,12 @@ module Net
|
|
96
94
|
#
|
97
95
|
def self.valid?(cls)
|
98
96
|
case cls
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
97
|
+
when String
|
98
|
+
CLASSES.key?(cls)
|
99
|
+
when Integer
|
100
|
+
CLASSES.invert.key?(cls)
|
101
|
+
else
|
102
|
+
raise ArgumentError, "Wrong cls class: #{cls.class}"
|
105
103
|
end
|
106
104
|
end
|
107
105
|
|
@@ -111,23 +109,22 @@ module Net
|
|
111
109
|
CLASSES.keys.sort.join("|")
|
112
110
|
end
|
113
111
|
|
114
|
-
|
115
|
-
private
|
112
|
+
private
|
116
113
|
|
117
114
|
# Initialize a new instance from a Class name.
|
118
115
|
def initialize_from_str(str)
|
119
116
|
key = str.to_s.upcase
|
120
|
-
@num
|
117
|
+
@num = CLASSES[key]
|
118
|
+
@str = key
|
121
119
|
end
|
122
120
|
|
123
121
|
# Initialize a new instance from the Class value.
|
124
122
|
def initialize_from_num(num)
|
125
123
|
key = num.to_i
|
126
|
-
@num
|
124
|
+
@num = key
|
125
|
+
@str = CLASSES.invert[key]
|
127
126
|
end
|
128
|
-
|
129
127
|
end
|
130
|
-
|
131
128
|
end
|
132
129
|
end
|
133
130
|
end
|
data/lib/net/dns/rr/cname.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Net # :nodoc:
|
2
2
|
module DNS
|
3
3
|
class RR
|
4
|
-
|
5
4
|
#
|
6
5
|
# = Canonical Name Record (CNAME)
|
7
6
|
#
|
@@ -12,13 +11,10 @@ module Net # :nodoc:
|
|
12
11
|
# Canonical means expected or real name.
|
13
12
|
#
|
14
13
|
class CNAME < RR
|
15
|
-
|
16
14
|
# Gets the canonical name value.
|
17
15
|
#
|
18
16
|
# Returns a String.
|
19
|
-
|
20
|
-
@cname
|
21
|
-
end
|
17
|
+
attr_reader :cname
|
22
18
|
|
23
19
|
# Gets the standardized value for this record,
|
24
20
|
# represented by the value of <tt>cname</tt>.
|
@@ -28,55 +24,51 @@ module Net # :nodoc:
|
|
28
24
|
cname.to_s
|
29
25
|
end
|
30
26
|
|
31
|
-
|
32
27
|
private
|
33
28
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
29
|
+
def subclass_new_from_hash(options)
|
30
|
+
if options.key?(:cname)
|
31
|
+
@cname = check_name(options[:cname])
|
32
|
+
else
|
33
|
+
raise ArgumentError, ":cname field is mandatory"
|
49
34
|
end
|
35
|
+
end
|
50
36
|
|
37
|
+
def subclass_new_from_string(str)
|
38
|
+
@cname = check_name(str)
|
39
|
+
end
|
51
40
|
|
52
|
-
|
53
|
-
|
54
|
-
|
41
|
+
def subclass_new_from_binary(data, offset)
|
42
|
+
@cname, offset = dn_expand(data, offset)
|
43
|
+
offset
|
44
|
+
end
|
55
45
|
|
56
|
-
|
57
|
-
|
58
|
-
|
46
|
+
def set_type
|
47
|
+
@type = Net::DNS::RR::Types.new("CNAME")
|
48
|
+
end
|
59
49
|
|
50
|
+
def get_inspect
|
51
|
+
value
|
52
|
+
end
|
60
53
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
66
|
-
name
|
54
|
+
def check_name(input)
|
55
|
+
name = input.to_s
|
56
|
+
unless name =~ /(\w\.?)+\s*$/ && name =~ /[a-zA-Z]/
|
57
|
+
raise ArgumentError, "Invalid Canonical Name `#{name}'"
|
67
58
|
end
|
68
59
|
|
69
|
-
|
70
|
-
|
71
|
-
@rdlength = @cname_pack.size
|
72
|
-
end
|
60
|
+
name
|
61
|
+
end
|
73
62
|
|
74
|
-
|
75
|
-
|
76
|
-
|
63
|
+
def build_pack
|
64
|
+
@cname_pack = pack_name(@cname)
|
65
|
+
@rdlength = @cname_pack.size
|
66
|
+
end
|
77
67
|
|
68
|
+
def get_data
|
69
|
+
@cname_pack
|
70
|
+
end
|
78
71
|
end
|
79
|
-
|
80
72
|
end
|
81
73
|
end
|
82
74
|
end
|