1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
/* |
6
|
|
|
* This file is part of Badcow DNS Library. |
7
|
|
|
* |
8
|
|
|
* (c) Samuel Williams <[email protected]> |
9
|
|
|
* |
10
|
|
|
* For the full copyright and license information, please view the LICENSE |
11
|
|
|
* file that was distributed with this source code. |
12
|
|
|
*/ |
13
|
|
|
|
14
|
|
|
namespace Badcow\DNS\Tests; |
15
|
|
|
|
16
|
|
|
use Badcow\DNS\Classes; |
17
|
|
|
use Badcow\DNS\Message; |
18
|
|
|
use Badcow\DNS\Opcode; |
19
|
|
|
use Badcow\DNS\Question; |
20
|
|
|
use Badcow\DNS\Rcode; |
21
|
|
|
use Badcow\DNS\Rdata\A; |
22
|
|
|
use Badcow\DNS\Rdata\MX; |
23
|
|
|
use Badcow\DNS\Rdata\NS; |
24
|
|
|
use Badcow\DNS\Rdata\UnsupportedTypeException; |
25
|
|
|
use Badcow\DNS\ResourceRecord; |
26
|
|
|
use Badcow\DNS\UnsetValueException; |
27
|
|
|
use PHPUnit\Framework\TestCase; |
28
|
|
|
|
29
|
|
|
class MessageTest extends TestCase |
30
|
|
|
{ |
31
|
|
|
/** |
32
|
|
|
* @throws \Exception |
33
|
|
|
*/ |
34
|
|
|
private function getWireTestData(int $n): string |
35
|
|
|
{ |
36
|
|
|
$filename = sprintf(__DIR__.'/Resources/wire/wire_test.data%d', $n); |
37
|
|
|
|
38
|
|
|
if (!file_exists($filename)) { |
39
|
|
|
throw new \Exception(sprintf('Could not locate resource "%s". FILE NOT FOUND.', $filename)); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
if (false === $data = file_get_contents($filename)) { |
43
|
|
|
throw new \Exception(sprintf('Could not access resource "%s".', $filename)); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
$data = preg_replace(['/0x/', '/#.*/', '/(?:\r|\n|\s)*/'], '', $data); |
47
|
|
|
|
48
|
|
|
return hex2bin($data); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @throws UnsupportedTypeException |
53
|
|
|
* @throws \Exception |
54
|
|
|
*/ |
55
|
|
|
public function testWire1(): void |
56
|
|
|
{ |
57
|
|
|
$data = $this->getWireTestData(1); |
58
|
|
|
|
59
|
|
|
$msg = Message::fromWire($data); |
60
|
|
|
|
61
|
|
|
$this->assertInstanceOf(Message::class, $msg); |
62
|
|
|
|
63
|
|
|
$this->assertEquals(10, $msg->getId()); |
64
|
|
|
$this->assertEquals(true, $msg->isResponse()); |
65
|
|
|
$this->assertEquals(false, $msg->isQuery()); |
66
|
|
|
$this->assertEquals(Opcode::QUERY, $msg->getOpcode()); |
67
|
|
|
$this->assertEquals(true, $msg->isAuthoritative()); |
68
|
|
|
$this->assertEquals(false, $msg->isTruncated()); |
69
|
|
|
$this->assertEquals(true, $msg->isRecursionDesired()); |
70
|
|
|
$this->assertEquals(true, $msg->isRecursionAvailable()); |
71
|
|
|
$this->assertEquals(0, $msg->getBit9()); |
72
|
|
|
$this->assertEquals(false, $msg->isAuthenticData()); |
73
|
|
|
$this->assertEquals(false, $msg->isCheckingDisabled()); |
74
|
|
|
$this->assertEquals(Rcode::NOERROR, $msg->getRcode()); |
75
|
|
|
|
76
|
|
|
$this->assertEquals(1, $msg->countQuestions()); |
77
|
|
|
$this->assertEquals(3, $msg->countAnswers()); |
78
|
|
|
$this->assertEquals(0, $msg->countAuthoritatives()); |
79
|
|
|
$this->assertEquals(3, $msg->countAdditionals()); |
80
|
|
|
|
81
|
|
|
$question = $msg->getQuestions()[0]; |
82
|
|
|
$this->assertEquals('vix.com.', $question->getName()); |
83
|
|
|
$this->assertEquals(1, $question->getClassId()); |
84
|
|
|
$this->assertEquals(2, $question->getTypeCode()); |
85
|
|
|
|
86
|
|
|
$ns1 = $msg->getAnswers()[0]; |
87
|
|
|
$this->assertInstanceOf(ResourceRecord::class, $ns1); |
88
|
|
|
$this->assertEquals('vix.com.', $ns1->getName()); |
89
|
|
|
$this->assertEquals(3600, $ns1->getTtl()); |
90
|
|
|
$this->assertEquals(Classes::INTERNET, $ns1->getClass()); |
91
|
|
|
$this->assertInstanceOf(NS::class, $ns1->getRdata()); |
92
|
|
|
$this->assertEquals('isrv1.pa.vix.com.', $ns1->getRdata()->getTarget()); |
|
|
|
|
93
|
|
|
|
94
|
|
|
$ns2 = $msg->getAnswers()[1]; |
95
|
|
|
$this->assertInstanceOf(ResourceRecord::class, $ns2); |
96
|
|
|
$this->assertEquals('vix.com.', $ns2->getName()); |
97
|
|
|
$this->assertEquals(3600, $ns2->getTtl()); |
98
|
|
|
$this->assertEquals(Classes::INTERNET, $ns2->getClass()); |
99
|
|
|
$this->assertInstanceOf(NS::class, $ns2->getRdata()); |
100
|
|
|
$this->assertEquals('ns-ext.vix.com.', $ns2->getRdata()->getTarget()); |
|
|
|
|
101
|
|
|
|
102
|
|
|
$ns3 = $msg->getAnswers()[2]; |
103
|
|
|
$this->assertInstanceOf(ResourceRecord::class, $ns3); |
104
|
|
|
$this->assertEquals('vix.com.', $ns3->getName()); |
105
|
|
|
$this->assertEquals(3600, $ns3->getTtl()); |
106
|
|
|
$this->assertEquals(Classes::INTERNET, $ns3->getClass()); |
107
|
|
|
$this->assertInstanceOf(NS::class, $ns3->getRdata()); |
108
|
|
|
$this->assertEquals('ns1.gnac.com.', $ns3->getRdata()->getTarget()); |
|
|
|
|
109
|
|
|
|
110
|
|
|
$a1 = $msg->getAdditionals()[0]; |
111
|
|
|
$this->assertInstanceOf(ResourceRecord::class, $a1); |
112
|
|
|
$this->assertEquals('isrv1.pa.vix.com.', $a1->getName()); |
113
|
|
|
$this->assertEquals(3600, $a1->getTtl()); |
114
|
|
|
$this->assertEquals(Classes::INTERNET, $a1->getClass()); |
115
|
|
|
$this->assertInstanceOf(A::class, $a1->getRdata()); |
116
|
|
|
$this->assertEquals('204.152.184.134', $a1->getRdata()->getAddress()); |
|
|
|
|
117
|
|
|
|
118
|
|
|
$a2 = $msg->getAdditionals()[1]; |
119
|
|
|
$this->assertInstanceOf(ResourceRecord::class, $a2); |
120
|
|
|
$this->assertEquals('ns-ext.vix.com.', $a2->getName()); |
121
|
|
|
$this->assertEquals(3600, $a2->getTtl()); |
122
|
|
|
$this->assertEquals(Classes::INTERNET, $a2->getClass()); |
123
|
|
|
$this->assertInstanceOf(A::class, $a2->getRdata()); |
124
|
|
|
$this->assertEquals('204.152.184.64', $a2->getRdata()->getAddress()); |
|
|
|
|
125
|
|
|
|
126
|
|
|
$a3 = $msg->getAdditionals()[2]; |
127
|
|
|
$this->assertInstanceOf(ResourceRecord::class, $a3); |
128
|
|
|
$this->assertEquals('ns1.gnac.com.', $a3->getName()); |
129
|
|
|
$this->assertEquals(172362, $a3->getTtl()); |
130
|
|
|
$this->assertEquals(Classes::INTERNET, $a3->getClass()); |
131
|
|
|
$this->assertInstanceOf(A::class, $a3->getRdata()); |
132
|
|
|
$this->assertEquals('198.151.248.246', $a3->getRdata()->getAddress()); |
|
|
|
|
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* @throws UnsupportedTypeException |
137
|
|
|
* @throws \Exception |
138
|
|
|
*/ |
139
|
|
View Code Duplication |
public function testWire2(): void |
|
|
|
|
140
|
|
|
{ |
141
|
|
|
$data = $this->getWireTestData(2); |
142
|
|
|
$msg = Message::fromWire($data); |
143
|
|
|
|
144
|
|
|
$this->assertInstanceOf(Message::class, $msg); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* @throws UnsupportedTypeException |
149
|
|
|
* @throws \Exception |
150
|
|
|
*/ |
151
|
|
View Code Duplication |
public function testWire3(): void |
|
|
|
|
152
|
|
|
{ |
153
|
|
|
$data = $this->getWireTestData(3); |
154
|
|
|
$msg = Message::fromWire($data); |
155
|
|
|
|
156
|
|
|
$this->assertInstanceOf(Message::class, $msg); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* @throws UnsupportedTypeException |
161
|
|
|
* @throws \Exception |
162
|
|
|
*/ |
163
|
|
|
public function testWire4(): void |
164
|
|
|
{ |
165
|
|
|
$data = $this->getWireTestData(4); |
166
|
|
|
$msg = Message::fromWire($data); |
167
|
|
|
|
168
|
|
|
$this->assertInstanceOf(Message::class, $msg); |
169
|
|
|
|
170
|
|
|
$this->assertEquals(6, $msg->getId()); |
171
|
|
|
$this->assertEquals(true, $msg->isResponse()); |
172
|
|
|
$this->assertEquals(Opcode::QUERY, $msg->getOpcode()); |
173
|
|
|
$this->assertEquals(false, $msg->isAuthoritative()); |
174
|
|
|
$this->assertEquals(false, $msg->isTruncated()); |
175
|
|
|
$this->assertEquals(true, $msg->isRecursionDesired()); |
176
|
|
|
$this->assertEquals(true, $msg->isRecursionAvailable()); |
177
|
|
|
$this->assertEquals(0, $msg->getBit9()); |
178
|
|
|
$this->assertEquals(false, $msg->isAuthenticData()); |
179
|
|
|
$this->assertEquals(false, $msg->isCheckingDisabled()); |
180
|
|
|
$this->assertEquals(Rcode::NOERROR, $msg->getRcode()); |
181
|
|
|
|
182
|
|
|
$this->assertEquals(1, $msg->countQuestions()); |
183
|
|
|
$this->assertEquals(7, $msg->countAnswers()); |
184
|
|
|
$this->assertEquals(2, $msg->countAuthoritatives()); |
185
|
|
|
$this->assertEquals(17, $msg->countAdditionals()); |
186
|
|
|
|
187
|
|
|
$question = $msg->getQuestions()[0]; |
188
|
|
|
$this->assertEquals('aol.com.', $question->getName()); |
189
|
|
|
$this->assertEquals(1, $question->getClassId()); |
190
|
|
|
$this->assertEquals(15, $question->getTypeCode()); |
191
|
|
|
|
192
|
|
|
$mx = $msg->getAnswers()[6]; |
193
|
|
|
$this->assertInstanceOf(ResourceRecord::class, $mx); |
194
|
|
|
$this->assertEquals('aol.com.', $mx->getName()); |
195
|
|
|
$this->assertEquals(3355, $mx->getTtl()); |
196
|
|
|
$this->assertEquals(Classes::INTERNET, $mx->getClass()); |
197
|
|
|
$this->assertInstanceOf(MX::class, $mx->getRdata()); |
198
|
|
|
$this->assertEquals(15, $mx->getRdata()->getPreference()); |
|
|
|
|
199
|
|
|
$this->assertEquals('zc.mx.aol.com.', $mx->getRdata()->getExchange()); |
|
|
|
|
200
|
|
|
|
201
|
|
|
$ns = $msg->getAuthoritatives()[1]; |
202
|
|
|
$this->assertInstanceOf(ResourceRecord::class, $ns); |
203
|
|
|
$this->assertEquals('aol.com.', $ns->getName()); |
204
|
|
|
$this->assertEquals(3355, $ns->getTtl()); |
205
|
|
|
$this->assertEquals(Classes::INTERNET, $ns->getClass()); |
206
|
|
|
$this->assertInstanceOf(NS::class, $ns->getRdata()); |
207
|
|
|
$this->assertEquals('DNS-02.NS.aol.com.', $ns->getRdata()->getTarget()); |
|
|
|
|
208
|
|
|
|
209
|
|
|
$a = $msg->getAdditionals()[14]; |
210
|
|
|
$this->assertInstanceOf(ResourceRecord::class, $a); |
211
|
|
|
$this->assertEquals('yc.mx.aol.com.', $a->getName()); |
212
|
|
|
$this->assertEquals(3356, $a->getTtl()); |
213
|
|
|
$this->assertEquals(Classes::INTERNET, $a->getClass()); |
214
|
|
|
$this->assertInstanceOf(A::class, $a->getRdata()); |
215
|
|
|
$this->assertEquals('205.188.156.130', $a->getRdata()->getAddress()); |
|
|
|
|
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* @throws UnsupportedTypeException |
220
|
|
|
* @throws UnsetValueException |
221
|
|
|
* @throws \Exception |
222
|
|
|
*/ |
223
|
|
View Code Duplication |
public function testWire5(): void |
|
|
|
|
224
|
|
|
{ |
225
|
|
|
$expectation = $this->getWireTestData(5); |
226
|
|
|
$msg = Message::fromWire($this->getWireTestData(1)); |
227
|
|
|
|
228
|
|
|
$this->assertEquals($expectation, $msg->toWire()); |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* @throws UnsetValueException |
233
|
|
|
* @throws UnsupportedTypeException |
234
|
|
|
* @throws \Exception |
235
|
|
|
*/ |
236
|
|
View Code Duplication |
public function testWire6(): void |
|
|
|
|
237
|
|
|
{ |
238
|
|
|
$expectation = $this->getWireTestData(6); |
239
|
|
|
$msg = Message::fromWire($this->getWireTestData(4)); |
240
|
|
|
|
241
|
|
|
$this->assertEquals($expectation, $msg->toWire()); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* @throws UnsupportedTypeException |
246
|
|
|
* @throws \Exception |
247
|
|
|
*/ |
248
|
|
|
public function testSetters(): void |
249
|
|
|
{ |
250
|
|
|
$msg = Message::fromWire($this->getWireTestData(4)); |
251
|
|
|
|
252
|
|
|
$questions = $msg->getQuestions(); |
253
|
|
|
$answers = $msg->getAnswers(); |
254
|
|
|
$additionals = $msg->getAdditionals(); |
255
|
|
|
$authoritatives = $msg->getAuthoritatives(); |
256
|
|
|
|
257
|
|
|
$this->assertEquals(1, $msg->countQuestions()); |
258
|
|
|
$this->assertEquals(7, $msg->countAnswers()); |
259
|
|
|
$this->assertEquals(2, $msg->countAuthoritatives()); |
260
|
|
|
$this->assertEquals(17, $msg->countAdditionals()); |
261
|
|
|
|
262
|
|
|
$msg->setQuestions([]); |
263
|
|
|
$msg->setAnswers([]); |
264
|
|
|
$msg->setAdditionals([]); |
265
|
|
|
$msg->setAuthoritatives([]); |
266
|
|
|
|
267
|
|
|
$this->assertEquals(0, $msg->countQuestions()); |
268
|
|
|
$this->assertEquals(0, $msg->countAnswers()); |
269
|
|
|
$this->assertEquals(0, $msg->countAuthoritatives()); |
270
|
|
|
$this->assertEquals(0, $msg->countAdditionals()); |
271
|
|
|
|
272
|
|
|
$msg->setQuestions($questions); |
273
|
|
|
$msg->setAnswers($answers); |
274
|
|
|
$msg->setAdditionals($additionals); |
275
|
|
|
$msg->setAuthoritatives($authoritatives); |
276
|
|
|
|
277
|
|
|
$this->assertEquals(1, $msg->countQuestions()); |
278
|
|
|
$this->assertEquals(7, $msg->countAnswers()); |
279
|
|
|
$this->assertEquals(2, $msg->countAuthoritatives()); |
280
|
|
|
$this->assertEquals(17, $msg->countAdditionals()); |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* @throws UnsetValueException |
285
|
|
|
* @throws UnsupportedTypeException |
286
|
|
|
* @throws \Exception |
287
|
|
|
*/ |
288
|
|
|
public function testMessage0(): void |
289
|
|
|
{ |
290
|
|
|
$expectation = $this->getWireTestData(0); |
291
|
|
|
$msg = new Message(); |
292
|
|
|
$msg->setId(42); |
293
|
|
|
$msg->setQuery(true); |
294
|
|
|
|
295
|
|
|
$question = new Question(); |
296
|
|
|
$question->setName('foo.bar.com.'); |
297
|
|
|
$question->setType('A'); |
298
|
|
|
$question->setClass('IN'); |
299
|
|
|
|
300
|
|
|
$msg->addQuestion($question); |
301
|
|
|
|
302
|
|
|
$this->assertEquals($expectation, $msg->toWire()); |
303
|
|
|
} |
304
|
|
|
} |
305
|
|
|
|
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: