gitlab-net-dns 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|