gitlab-net-dns 0.9.1
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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.gitlab-ci.yml +20 -0
- data/.rspec +1 -0
- data/.rubocop.yml +3 -0
- data/.rubocop_defaults.yml +359 -0
- data/.rubocop_todo.yml +207 -0
- data/.travis.yml +13 -0
- data/CHANGELOG.md +113 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +56 -0
- data/README.md +172 -0
- data/Rakefile +38 -0
- data/THANKS.rdoc +24 -0
- data/bin/console +14 -0
- data/demo/check_soa.rb +104 -0
- data/demo/threads.rb +18 -0
- data/gitlab-net-dns.gemspec +24 -0
- data/lib/net/dns.rb +104 -0
- data/lib/net/dns/header.rb +705 -0
- data/lib/net/dns/names.rb +120 -0
- data/lib/net/dns/packet.rb +560 -0
- data/lib/net/dns/question.rb +185 -0
- data/lib/net/dns/resolver.rb +1214 -0
- data/lib/net/dns/resolver/socks.rb +148 -0
- data/lib/net/dns/resolver/timeouts.rb +70 -0
- data/lib/net/dns/rr.rb +356 -0
- data/lib/net/dns/rr/a.rb +114 -0
- data/lib/net/dns/rr/aaaa.rb +94 -0
- data/lib/net/dns/rr/classes.rb +130 -0
- data/lib/net/dns/rr/cname.rb +74 -0
- data/lib/net/dns/rr/hinfo.rb +96 -0
- data/lib/net/dns/rr/mr.rb +70 -0
- data/lib/net/dns/rr/mx.rb +82 -0
- data/lib/net/dns/rr/ns.rb +70 -0
- data/lib/net/dns/rr/null.rb +50 -0
- data/lib/net/dns/rr/ptr.rb +77 -0
- data/lib/net/dns/rr/soa.rb +75 -0
- data/lib/net/dns/rr/srv.rb +41 -0
- data/lib/net/dns/rr/txt.rb +58 -0
- data/lib/net/dns/rr/types.rb +191 -0
- data/lib/net/dns/version.rb +8 -0
- data/spec/fixtures/resolv.conf +4 -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 +13 -0
- data/test/unit/header_test.rb +164 -0
- data/test/unit/names_test.rb +21 -0
- data/test/unit/packet_test.rb +47 -0
- data/test/unit/question_test.rb +81 -0
- data/test/unit/resolver_test.rb +114 -0
- data/test/unit/rr/a_test.rb +106 -0
- data/test/unit/rr/aaaa_test.rb +102 -0
- data/test/unit/rr/classes_test.rb +83 -0
- data/test/unit/rr/cname_test.rb +90 -0
- data/test/unit/rr/hinfo_test.rb +111 -0
- data/test/unit/rr/mr_test.rb +99 -0
- data/test/unit/rr/mx_test.rb +106 -0
- data/test/unit/rr/ns_test.rb +80 -0
- data/test/unit/rr/types_test.rb +71 -0
- data/test/unit/rr_test.rb +127 -0
- metadata +172 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
module Net # :nodoc:
|
2
|
+
module DNS
|
3
|
+
class RR
|
4
|
+
#------------------------------------------------------------
|
5
|
+
# RR type TXT
|
6
|
+
#------------------------------------------------------------
|
7
|
+
class TXT < RR
|
8
|
+
attr_reader :txt
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def build_pack
|
13
|
+
str = ""
|
14
|
+
@txt.split(" ").each do |txt|
|
15
|
+
str += [txt.length, txt].pack("C a*")
|
16
|
+
end
|
17
|
+
@txt_pack = str
|
18
|
+
@rdlength = @txt_pack.size
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_data
|
22
|
+
@txt_pack
|
23
|
+
end
|
24
|
+
|
25
|
+
def subclass_new_from_hash(args)
|
26
|
+
if args.key? :txt
|
27
|
+
@txt = args[:txt].strip
|
28
|
+
else
|
29
|
+
raise ArgumentError, ":txt field is mandatory but missing"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def subclass_new_from_string(str)
|
34
|
+
@txt = str.strip
|
35
|
+
end
|
36
|
+
|
37
|
+
def subclass_new_from_binary(data, offset)
|
38
|
+
off_end = offset + @rdlength
|
39
|
+
@txt = ""
|
40
|
+
while offset < off_end
|
41
|
+
len = data.unpack("@#{offset} C")[0]
|
42
|
+
offset += 1
|
43
|
+
str = data[offset..offset + len - 1]
|
44
|
+
offset += len
|
45
|
+
@txt << str << " "
|
46
|
+
end
|
47
|
+
offset
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def set_type
|
53
|
+
@type = Net::DNS::RR::Types.new("TXT")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
module Net # :nodoc:
|
2
|
+
module DNS
|
3
|
+
class RR
|
4
|
+
# This is an auxiliary class to handle RR type field in a DNS packet.
|
5
|
+
class Types
|
6
|
+
TYPES = {
|
7
|
+
'SIGZERO' => 0, # RFC2931 consider this a pseudo type
|
8
|
+
'A' => 1, # RFC 1035, Section 3.4.1
|
9
|
+
'NS' => 2, # RFC 1035, Section 3.3.11
|
10
|
+
'MD' => 3, # RFC 1035, Section 3.3.4 (obsolete)
|
11
|
+
'MF' => 4, # RFC 1035, Section 3.3.5 (obsolete)
|
12
|
+
'CNAME' => 5, # RFC 1035, Section 3.3.1
|
13
|
+
'SOA' => 6, # RFC 1035, Section 3.3.13
|
14
|
+
'MB' => 7, # RFC 1035, Section 3.3.3
|
15
|
+
'MG' => 8, # RFC 1035, Section 3.3.6
|
16
|
+
'MR' => 9, # RFC 1035, Section 3.3.8
|
17
|
+
'NULL' => 10, # RFC 1035, Section 3.3.10
|
18
|
+
'WKS' => 11, # RFC 1035, Section 3.4.2 (deprecated)
|
19
|
+
'PTR' => 12, # RFC 1035, Section 3.3.12
|
20
|
+
'HINFO' => 13, # RFC 1035, Section 3.3.2
|
21
|
+
'MINFO' => 14, # RFC 1035, Section 3.3.7
|
22
|
+
'MX' => 15, # RFC 1035, Section 3.3.9
|
23
|
+
'TXT' => 16, # RFC 1035, Section 3.3.14
|
24
|
+
'RP' => 17, # RFC 1183, Section 2.2
|
25
|
+
'AFSDB' => 18, # RFC 1183, Section 1
|
26
|
+
'X25' => 19, # RFC 1183, Section 3.1
|
27
|
+
'ISDN' => 20, # RFC 1183, Section 3.2
|
28
|
+
'RT' => 21, # RFC 1183, Section 3.3
|
29
|
+
'NSAP' => 22, # RFC 1706, Section 5
|
30
|
+
'NSAP_PTR' => 23, # RFC 1348 (obsolete)
|
31
|
+
# The following 2 RRs are impemented in Net::DNS::SEC, TODO
|
32
|
+
'SIG' => 24, # RFC 2535, Section 4.1
|
33
|
+
'KEY' => 25, # RFC 2535, Section 3.1
|
34
|
+
'PX' => 26, # RFC 2163,
|
35
|
+
'GPOS' => 27, # RFC 1712 (obsolete)
|
36
|
+
'AAAA' => 28, # RFC 1886, Section 2.1
|
37
|
+
'LOC' => 29, # RFC 1876
|
38
|
+
# The following RR is implemented in Net::DNS::SEC, TODO
|
39
|
+
'NXT' => 30, # RFC 2535, Section 5.2
|
40
|
+
'EID' => 31, # draft-ietf-nimrod-dns-xx.txt
|
41
|
+
'NIMLOC' => 32, # draft-ietf-nimrod-dns-xx.txt
|
42
|
+
'SRV' => 33, # RFC 2052
|
43
|
+
'ATMA' => 34, # ???
|
44
|
+
'NAPTR' => 35, # RFC 2168
|
45
|
+
'KX' => 36, # RFC 2230
|
46
|
+
'CERT' => 37, # RFC 2538
|
47
|
+
'DNAME' => 39, # RFC 2672
|
48
|
+
'OPT' => 41, # RFC 2671
|
49
|
+
# The following 4 RRs are implemented in Net::DNS::SEC TODO
|
50
|
+
'DS' => 43, # draft-ietf-dnsext-delegation-signer
|
51
|
+
'SSHFP' => 44, # draft-ietf-secsh-dns (No RFC # yet at time of coding)
|
52
|
+
'RRSIG' => 46, # draft-ietf-dnsext-dnssec-2535typecode-change
|
53
|
+
'NSEC' => 47, # draft-ietf-dnsext-dnssec-2535typecode-change
|
54
|
+
'DNSKEY' => 48, # draft-ietf-dnsext-dnssec-2535typecode-change
|
55
|
+
'UINFO' => 100, # non-standard
|
56
|
+
'UID' => 101, # non-standard
|
57
|
+
'GID' => 102, # non-standard
|
58
|
+
'UNSPEC' => 103, # non-standard
|
59
|
+
'TKEY' => 249, # RFC 2930
|
60
|
+
'TSIG' => 250, # RFC 2931
|
61
|
+
'IXFR' => 251, # RFC 1995
|
62
|
+
'AXFR' => 252, # RFC 1035
|
63
|
+
'MAILB' => 253, # RFC 1035 (MB, MG, MR)
|
64
|
+
'MAILA' => 254, # RFC 1035 (obsolete - see MX)
|
65
|
+
'ANY' => 255, # RFC 1035
|
66
|
+
}.freeze
|
67
|
+
|
68
|
+
# The default value when type is nil in Resource Records
|
69
|
+
@@default = TYPES["A"]
|
70
|
+
|
71
|
+
def self.default
|
72
|
+
@@default
|
73
|
+
end
|
74
|
+
|
75
|
+
# Be able to control the default type to assign when
|
76
|
+
# type is +nil+. Default to +A+
|
77
|
+
def self.default=(str)
|
78
|
+
if TYPES.key? str
|
79
|
+
@@default = TYPES[str]
|
80
|
+
else
|
81
|
+
raise ArgumentError, "Unknown type #{str}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Checks whether +type+ is a valid RR type.
|
86
|
+
def self.valid?(type)
|
87
|
+
case type
|
88
|
+
when String
|
89
|
+
TYPES.key?(type)
|
90
|
+
when Integer
|
91
|
+
TYPES.invert.key?(type)
|
92
|
+
else
|
93
|
+
raise ArgumentError, "Wrong type class: #{type.class}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns the type in string format, as "A" or "NS",
|
98
|
+
# given the numeric value
|
99
|
+
def self.to_str(type)
|
100
|
+
case type
|
101
|
+
when Integer
|
102
|
+
if TYPES.invert.key? type
|
103
|
+
TYPES.invert[type]
|
104
|
+
else
|
105
|
+
raise ArgumentError, "Unknown type number #{type}"
|
106
|
+
end
|
107
|
+
else
|
108
|
+
raise ArgumentError, "Wrong type class: #{type.class}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Gives in output the keys from the +Types+ hash
|
113
|
+
# in a format suited for regexps
|
114
|
+
def self.regexp
|
115
|
+
# Longest ones go first, so the regex engine will match AAAA before A.
|
116
|
+
TYPES.keys.sort { |a, b| b.length <=> a.length }.join("|")
|
117
|
+
end
|
118
|
+
|
119
|
+
# Creates a new object representing an RR type. Performs some
|
120
|
+
# checks on the argument validity too. Il +type+ is +nil+, the
|
121
|
+
# default value is +ANY+ or the one set with Types.default=
|
122
|
+
def initialize(type)
|
123
|
+
case type
|
124
|
+
when String
|
125
|
+
# type in the form "A" or "NS"
|
126
|
+
new_from_string(type.upcase)
|
127
|
+
when Integer
|
128
|
+
# type in numeric form
|
129
|
+
new_from_num(type)
|
130
|
+
when nil
|
131
|
+
# default type, control with Types.default=
|
132
|
+
@str = TYPES.invert[@@default]
|
133
|
+
@num = @@default
|
134
|
+
else
|
135
|
+
raise ArgumentError, "Wrong type class: #{type.class}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Returns the type in number format
|
140
|
+
# (default for normal use)
|
141
|
+
def inspect
|
142
|
+
@num
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns the type in string format,
|
146
|
+
# i.d. "A" or "NS" or such a string.
|
147
|
+
def to_s
|
148
|
+
@str
|
149
|
+
end
|
150
|
+
|
151
|
+
# Returns the type in numeric format,
|
152
|
+
# usable by the pack methods for data transfers
|
153
|
+
def to_i
|
154
|
+
@num.to_i
|
155
|
+
end
|
156
|
+
|
157
|
+
def to_str
|
158
|
+
@num.to_s
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
# Constructor for string data type.
|
164
|
+
def new_from_string(type)
|
165
|
+
case type
|
166
|
+
when /^TYPE\\d+/
|
167
|
+
# TODO!!!
|
168
|
+
else
|
169
|
+
# String with name of type
|
170
|
+
if TYPES.key? type
|
171
|
+
@str = type
|
172
|
+
@num = TYPES[type]
|
173
|
+
else
|
174
|
+
raise ArgumentError, "Unknown type #{type}"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# Contructor for numeric data type.
|
180
|
+
def new_from_num(type)
|
181
|
+
if TYPES.invert.key? type
|
182
|
+
@num = type
|
183
|
+
@str = TYPES.invert[type]
|
184
|
+
else
|
185
|
+
raise ArgumentError, "Unkown type number #{type}"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'net/dns'
|
3
|
+
|
4
|
+
unless defined?(SPEC_ROOT)
|
5
|
+
SPEC_ROOT = File.expand_path(__dir__)
|
6
|
+
end
|
7
|
+
|
8
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
9
|
+
# in spec/support/ and its subdirectories.
|
10
|
+
Dir[File.join(SPEC_ROOT, "support/**/*.rb")].each { |f| require f }
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.mock_with :rspec
|
14
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'net/dns/resolver/timeouts'
|
3
|
+
|
4
|
+
describe Net::DNS::Resolver::DnsTimeout do
|
5
|
+
subject { described_class.new(10) }
|
6
|
+
|
7
|
+
describe "#initialize" do
|
8
|
+
it "returns an instance of DnsTimeout" do
|
9
|
+
expect(subject.class).to be(described_class)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "sets timeout" do
|
13
|
+
expect(described_class.new(0).seconds).to eq(0)
|
14
|
+
expect(described_class.new(10).seconds).to eq(10)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "raises ArgumentError when timeout is invalid" do
|
18
|
+
expect { described_class.new(nil) }.to raise_error(ArgumentError)
|
19
|
+
expect { described_class.new("") }.to raise_error(ArgumentError)
|
20
|
+
expect { described_class.new("foo") }.to raise_error(ArgumentError)
|
21
|
+
expect { described_class.new(-1) }.to raise_error(ArgumentError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#to_s" do
|
26
|
+
it "returns the seconds" do
|
27
|
+
expect(subject.to_s).to eq("10")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#timeout" do
|
32
|
+
it "requires a block" do
|
33
|
+
expect { subject.timeout }.to raise_error(LocalJumpError)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'net/dns/resolver/timeouts'
|
3
|
+
|
4
|
+
describe Net::DNS::Resolver::TcpTimeout do
|
5
|
+
subject { described_class.new(10) }
|
6
|
+
|
7
|
+
it "inherits from DnsTimeout" do
|
8
|
+
expect(described_class.ancestors).to include(Net::DNS::Resolver::DnsTimeout)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#initialize" do
|
12
|
+
it "returns an instance of TcpTimeout" do
|
13
|
+
expect(subject.class).to be(described_class)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "sets timeout" do
|
17
|
+
expect(described_class.new(0).seconds).to eq(0)
|
18
|
+
expect(described_class.new(10).seconds).to eq(10)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "raises ArgumentError when timeout is invalid" do
|
22
|
+
expect { described_class.new(nil) }.to raise_error(ArgumentError)
|
23
|
+
expect { described_class.new("") }.to raise_error(ArgumentError)
|
24
|
+
expect { described_class.new("foo") }.to raise_error(ArgumentError)
|
25
|
+
expect { described_class.new(-1) }.to raise_error(ArgumentError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#to_s" do
|
30
|
+
it "returns infinite when seconds is 0" do
|
31
|
+
expect(described_class.new(0).to_s).to eq("infinite")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns the seconds" do
|
35
|
+
expect(subject.to_s).to eq("10")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#pretty_to_s" do
|
40
|
+
it "returns a more verbose version" do
|
41
|
+
expect(described_class.new(30).pretty_to_s).to eq("30 seconds")
|
42
|
+
expect(described_class.new(90).pretty_to_s).to eq("1 minutes and 30 seconds")
|
43
|
+
expect(described_class.new(3690).pretty_to_s).to eq("1 hours, 1 minutes and 30 seconds")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'net/dns/resolver/timeouts'
|
3
|
+
|
4
|
+
describe Net::DNS::Resolver::UdpTimeout do
|
5
|
+
subject { described_class.new(10) }
|
6
|
+
|
7
|
+
it "inherits from DnsTimeout" do
|
8
|
+
expect(described_class.ancestors).to include(Net::DNS::Resolver::DnsTimeout)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#initialize" do
|
12
|
+
it "returns an instance of TcpTimeout" do
|
13
|
+
expect(subject.class).to be(described_class)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "sets timeout" do
|
17
|
+
expect(described_class.new(0).seconds).to eq(0)
|
18
|
+
expect(described_class.new(10).seconds).to eq(10)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "raises ArgumentError when timeout is invalid" do
|
22
|
+
expect { described_class.new(nil) }.to raise_error(ArgumentError)
|
23
|
+
expect { described_class.new("") }.to raise_error(ArgumentError)
|
24
|
+
expect { described_class.new("foo") }.to raise_error(ArgumentError)
|
25
|
+
expect { described_class.new(-1) }.to raise_error(ArgumentError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#to_s" do
|
30
|
+
it "returns infinite when seconds is 0" do
|
31
|
+
expect(described_class.new(0).to_s).to eq("not defined")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns the seconds" do
|
35
|
+
expect(subject.to_s).to eq("10")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#pretty_to_s" do
|
40
|
+
it "returns a more verbose version" do
|
41
|
+
expect(described_class.new(30).pretty_to_s).to eq("30 seconds")
|
42
|
+
expect(described_class.new(90).pretty_to_s).to eq("1 minutes and 30 seconds")
|
43
|
+
expect(described_class.new(3690).pretty_to_s).to eq("1 hours, 1 minutes and 30 seconds")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "minitest/reporters"
|
3
|
+
|
4
|
+
Minitest::Reporters.use! Minitest::Reporters::DefaultReporter.new(color: true)
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
7
|
+
require "net/dns"
|
8
|
+
|
9
|
+
module Minitest::Assertions
|
10
|
+
def assert_nothing_raised(*)
|
11
|
+
yield
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'net/dns/header'
|
3
|
+
|
4
|
+
class HeaderTest < Minitest::Test
|
5
|
+
include Net::DNS
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@default = Header.new
|
9
|
+
@hash = Header.new(id: 441,
|
10
|
+
qr: 1,
|
11
|
+
opCode: Header::IQUERY,
|
12
|
+
aa: 1,
|
13
|
+
tc: 1,
|
14
|
+
rd: 0,
|
15
|
+
cd: 0,
|
16
|
+
ad: 0,
|
17
|
+
ra: 1,
|
18
|
+
rCode: Header::RCode::FORMAT,
|
19
|
+
qdCount: 1,
|
20
|
+
anCount: 2,
|
21
|
+
nsCount: 3,
|
22
|
+
arCount: 3)
|
23
|
+
|
24
|
+
@modified = Header.new
|
25
|
+
@modified.id = 442
|
26
|
+
@modified.qr = true
|
27
|
+
@modified.opCode = Header::IQUERY
|
28
|
+
@modified.aa = true
|
29
|
+
@modified.tc = true
|
30
|
+
@modified.rd = false
|
31
|
+
@modified.cd = false
|
32
|
+
@modified.ra = true
|
33
|
+
@modified.rCode = Header::RCode::FORMAT
|
34
|
+
@modified.qdCount = 1
|
35
|
+
@modified.anCount = 2
|
36
|
+
@modified.nsCount = 3
|
37
|
+
@modified.arCount = 3
|
38
|
+
|
39
|
+
@data = @modified.data
|
40
|
+
num = [(@data.unpack("n")[0] + 1)].pack("n")
|
41
|
+
@data[0] = num[0]
|
42
|
+
@data[1] = num[1]
|
43
|
+
@binary = Header.parse(@data)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_simple
|
47
|
+
assert_equal(@default.query?, true)
|
48
|
+
assert_equal(@default.response?, false)
|
49
|
+
assert_equal(@default.opCode, Header::QUERY)
|
50
|
+
assert_equal(@default.auth?, false)
|
51
|
+
assert_equal(@default.truncated?, false)
|
52
|
+
assert_equal(@default.recursive?, true)
|
53
|
+
assert_equal(@default.checking?, true)
|
54
|
+
assert_equal(@default.verified?, false)
|
55
|
+
assert_equal(@default.r_available?, false)
|
56
|
+
assert_equal(@default.rCode.code, Header::RCode::NOERROR)
|
57
|
+
assert_equal(@default.qdCount, 1)
|
58
|
+
assert_equal(@default.anCount, 0)
|
59
|
+
assert_equal(@default.nsCount, 0)
|
60
|
+
assert_equal(@default.arCount, 0)
|
61
|
+
|
62
|
+
assert_equal(@hash.id, 441)
|
63
|
+
assert_equal(@hash.query?, false)
|
64
|
+
assert_equal(@hash.response?, true)
|
65
|
+
assert_equal(@hash.opCode, Header::IQUERY)
|
66
|
+
assert_equal(@hash.auth?, true)
|
67
|
+
assert_equal(@hash.truncated?, true)
|
68
|
+
assert_equal(@hash.recursive?, false)
|
69
|
+
assert_equal(@hash.checking?, true)
|
70
|
+
assert_equal(@hash.verified?, false)
|
71
|
+
assert_equal(@hash.r_available?, true)
|
72
|
+
assert_equal(@hash.rCode.code, Header::RCode::FORMAT)
|
73
|
+
assert_equal(@hash.qdCount, 1)
|
74
|
+
assert_equal(@hash.anCount, 2)
|
75
|
+
assert_equal(@hash.nsCount, 3)
|
76
|
+
assert_equal(@hash.arCount, 3)
|
77
|
+
|
78
|
+
assert_equal(@modified.id, 442)
|
79
|
+
assert_equal(@modified.query?, false)
|
80
|
+
assert_equal(@modified.response?, true)
|
81
|
+
assert_equal(@modified.opCode, Header::IQUERY)
|
82
|
+
assert_equal(@modified.auth?, true)
|
83
|
+
assert_equal(@modified.truncated?, true)
|
84
|
+
assert_equal(@modified.recursive?, false)
|
85
|
+
assert_equal(@modified.checking?, true)
|
86
|
+
assert_equal(@modified.verified?, false)
|
87
|
+
assert_equal(@modified.r_available?, true)
|
88
|
+
assert_equal(@modified.rCode.code, Header::RCode::FORMAT)
|
89
|
+
assert_equal(@modified.qdCount, 1)
|
90
|
+
assert_equal(@modified.anCount, 2)
|
91
|
+
assert_equal(@modified.nsCount, 3)
|
92
|
+
assert_equal(@modified.arCount, 3)
|
93
|
+
|
94
|
+
assert_equal(@binary.data, @data)
|
95
|
+
|
96
|
+
assert_equal(@binary.id, 443)
|
97
|
+
assert_equal(@binary.query?, false)
|
98
|
+
assert_equal(@binary.response?, true)
|
99
|
+
assert_equal(@binary.opCode, Header::IQUERY)
|
100
|
+
assert_equal(@binary.auth?, true)
|
101
|
+
assert_equal(@binary.truncated?, true)
|
102
|
+
assert_equal(@binary.recursive?, false)
|
103
|
+
assert_equal(@binary.checking?, true)
|
104
|
+
assert_equal(@binary.verified?, false)
|
105
|
+
assert_equal(@binary.r_available?, true)
|
106
|
+
assert_equal(@binary.rCode.code, Header::RCode::FORMAT)
|
107
|
+
assert_equal(@binary.qdCount, 1)
|
108
|
+
assert_equal(@binary.anCount, 2)
|
109
|
+
assert_equal(@binary.nsCount, 3)
|
110
|
+
assert_equal(@binary.arCount, 3)
|
111
|
+
|
112
|
+
assert_raises(ArgumentError) do
|
113
|
+
Header.new([])
|
114
|
+
end
|
115
|
+
assert_raises(ArgumentError) do
|
116
|
+
Header.parse([])
|
117
|
+
end
|
118
|
+
assert_raises(ArgumentError) do
|
119
|
+
Header.parse("aa")
|
120
|
+
end
|
121
|
+
assert_raises(ArgumentError) do
|
122
|
+
@default.id = 1_000_000
|
123
|
+
end
|
124
|
+
assert_raises(ArgumentError) do
|
125
|
+
@default.qr = 2
|
126
|
+
end
|
127
|
+
assert_raises(Header::WrongOpcodeError) do
|
128
|
+
@default.opCode = 4
|
129
|
+
end
|
130
|
+
assert_raises(ArgumentError) do
|
131
|
+
@default.aa = 2
|
132
|
+
end
|
133
|
+
assert_raises(ArgumentError) do
|
134
|
+
@default.tc = 2
|
135
|
+
end
|
136
|
+
assert_raises(Header::WrongRecursiveError) do
|
137
|
+
@default.recursive = 2
|
138
|
+
end
|
139
|
+
assert_raises(ArgumentError) do
|
140
|
+
@default.ra = 2
|
141
|
+
end
|
142
|
+
assert_raises(ArgumentError) do
|
143
|
+
@default.cd = 2
|
144
|
+
end
|
145
|
+
assert_raises(ArgumentError) do
|
146
|
+
@default.ad = 2
|
147
|
+
end
|
148
|
+
assert_raises(ArgumentError) do
|
149
|
+
@default.rCode = 46
|
150
|
+
end
|
151
|
+
assert_raises(Header::WrongCountError) do
|
152
|
+
@default.qdCount = 100_000
|
153
|
+
end
|
154
|
+
assert_raises(Header::WrongCountError) do
|
155
|
+
@default.anCount = 100_000
|
156
|
+
end
|
157
|
+
assert_raises(Header::WrongCountError) do
|
158
|
+
@default.nsCount = 100_000
|
159
|
+
end
|
160
|
+
assert_raises(Header::WrongCountError) do
|
161
|
+
@default.arCount = 100_000
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|