Skip to content

Commit 0934c7b

Browse files
committed
[Dns] Move header logic to HeaderBag, messages to Model package
1 parent 976b831 commit 0934c7b

6 files changed

Lines changed: 103 additions & 48 deletions

File tree

BinaryDumper.php

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,43 @@
22

33
namespace React\Dns;
44

5+
use React\Dns\Model\Message;
6+
use React\Dns\Model\HeaderBag;
7+
58
class BinaryDumper
69
{
710
public function toBinary(Message $message)
811
{
912
$data = '';
1013

11-
$data .= $this->headerToBinary($message->header);
12-
$data .= $this->questionToBinary($message->question);
14+
$data .= $this->headerToBinary($message->headers);
15+
$data .= $this->questionToBinary($message->questions);
1316

1417
return $data;
1518
}
1619

17-
private function headerToBinary(array $header)
20+
private function headerToBinary(HeaderBag $header)
1821
{
1922
$data = '';
2023

21-
$data .= pack('n', $header['id']);
24+
$data .= pack('n', $header->get('id'));
2225

2326
$flags = 0x00;
24-
$flags = ($flags << 1) | $header['qr'];
25-
$flags = ($flags << 4) | $header['opcode'];
26-
$flags = ($flags << 1) | $header['aa'];
27-
$flags = ($flags << 1) | $header['tc'];
28-
$flags = ($flags << 1) | $header['rd'];
29-
$flags = ($flags << 1) | $header['ra'];
30-
$flags = ($flags << 3) | $header['z'];
31-
$flags = ($flags << 4) | $header['rcode'];
27+
$flags = ($flags << 1) | $header->get('qr');
28+
$flags = ($flags << 4) | $header->get('opcode');
29+
$flags = ($flags << 1) | $header->get('aa');
30+
$flags = ($flags << 1) | $header->get('tc');
31+
$flags = ($flags << 1) | $header->get('rd');
32+
$flags = ($flags << 1) | $header->get('ra');
33+
$flags = ($flags << 3) | $header->get('z');
34+
$flags = ($flags << 4) | $header->get('rcode');
3235

3336
$data .= pack('n', $flags);
3437

35-
$data .= pack('n', $header['qdCount']);
36-
$data .= pack('n', $header['anCount']);
37-
$data .= pack('n', $header['nsCount']);
38-
$data .= pack('n', $header['arCount']);
38+
$data .= pack('n', $header->get('qdCount'));
39+
$data .= pack('n', $header->get('anCount'));
40+
$data .= pack('n', $header->get('nsCount'));
41+
$data .= pack('n', $header->get('arCount'));
3942

4043
return $data;
4144
}

Model/HeaderBag.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace React\Dns\Model;
4+
5+
class HeaderBag
6+
{
7+
public $data = '';
8+
9+
public $attributes = array(
10+
'qdCount' => 0,
11+
'anCount' => 0,
12+
'nsCount' => 0,
13+
'arCount' => 0,
14+
'qr' => 0,
15+
'opcode' => Message::OPCODE_QUERY,
16+
'aa' => 0,
17+
'tc' => 0,
18+
'rd' => 0,
19+
'ra' => 0,
20+
'z' => 0,
21+
'rcode' => Message::RCODE_OK,
22+
);
23+
24+
public function get($name)
25+
{
26+
return isset($this->attributes[$name]) ? $this->attributes[$name] : null;
27+
}
28+
29+
public function set($name, $value)
30+
{
31+
$this->attributes[$name] = $value;
32+
}
33+
34+
public function isQuery()
35+
{
36+
return 0 === $this->attributes['qr'];
37+
}
38+
39+
public function isResponse()
40+
{
41+
return 1 === $this->attributes['qr'];
42+
}
43+
44+
public function populateCounts(Message $message)
45+
{
46+
$this->attributes['qdCount'] = count($message->questions);
47+
$this->attributes['anCount'] = count($message->answers);
48+
$this->attributes['nsCount'] = count($message->authority);
49+
$this->attributes['arCount'] = count($message->additional);
50+
}
51+
}

Message.php renamed to Model/Message.php

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace React\Dns;
3+
namespace React\Dns\Model;
44

55
class Message
66
{
@@ -27,24 +27,19 @@ class Message
2727

2828
public $data = '';
2929

30-
public $header = array();
31-
public $question = array();
32-
public $answer = array();
30+
public $headers;
31+
public $questions = array();
32+
public $answers = array();
3333
public $authority = array();
3434
public $additional = array();
3535

36-
public function getId()
36+
public function __construct()
3737
{
38-
return $this->header['id'];
38+
$this->headers = new HeaderBag();
3939
}
4040

41-
public function isQuery()
41+
public function prepare()
4242
{
43-
return 0 === $this->header['qr'];
44-
}
45-
46-
public function isResponse()
47-
{
48-
return 1 === $this->header['qr'];
43+
$this->headers->populateCounts($this);
4944
}
5045
}

Record.php renamed to Model/Record.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace React\Dns;
3+
namespace React\Dns\Model;
44

55
class Record
66
{

Parser.php

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace React\Dns;
44

5+
use React\Dns\Model\Message;
6+
use React\Dns\Model\Record;
7+
58
/**
69
* DNS protocol parser
710
*
@@ -13,19 +16,19 @@ public function parseChunk($data, Message $message)
1316
{
1417
$message->data .= $data;
1518

16-
if (!$message->header) {
19+
if (!$message->headers->get('id')) {
1720
if (!$this->parseHeader($message)) {
1821
return;
1922
}
2023
}
2124

22-
if ($message->header['qdCount'] != count($message->question)) {
25+
if ($message->headers->get('qdCount') != count($message->questions)) {
2326
if (!$this->parseQuestion($message)) {
2427
return;
2528
}
2629
}
2730

28-
if ($message->header['anCount'] != count($message->answer)) {
31+
if ($message->headers->get('anCount') != count($message->answers)) {
2932
if (!$this->parseAnswer($message)) {
3033
return;
3134
}
@@ -52,8 +55,13 @@ private function parseHeader(Message $message)
5255
$opcode = ($fields >> 11) & chr(bindec('1111'));
5356
$qr = ($fields >> 15) & 1;
5457

55-
$message->header = compact('id', 'qdCount', 'anCount', 'nsCount', 'arCount',
56-
'qr', 'opcode', 'aa', 'tc', 'rd', 'ra', 'z', 'rcode');
58+
$vars = compact('id', 'qdCount', 'anCount', 'nsCount', 'arCount',
59+
'qr', 'opcode', 'aa', 'tc', 'rd', 'ra', 'z', 'rcode');
60+
61+
62+
foreach ($vars as $name => $value) {
63+
$message->headers->set($name, $value);
64+
}
5765

5866
return $message;
5967
}
@@ -96,13 +104,13 @@ private function parseQuestion(Message $message)
96104

97105
$message->data = substr($message->data, $consumed) ?: '';
98106

99-
$message->question[] = array(
107+
$message->questions[] = array(
100108
'name' => implode('.', $labels),
101109
'type' => $type,
102110
'class' => $class,
103111
);
104112

105-
if ($message->header['qdCount'] != count($message->question)) {
113+
if ($message->headers->get('qdCount') != count($message->questions)) {
106114
return $this->parseQuestion($message);
107115
}
108116

@@ -122,7 +130,7 @@ private function parseAnswer(Message $message)
122130

123131
if ($nameOffset & $mask) {
124132
$consumed += 2;
125-
$labels[] = $message->question[0]['name'];
133+
$labels[] = $message->questions[0]['name'];
126134
// TODO: get proper offset
127135
} else {
128136
$length = ord(substr($message->data, $consumed, 1));
@@ -171,7 +179,7 @@ private function parseAnswer(Message $message)
171179
$record->ttl = $this->signedLongToUnsignedLong($ttl);
172180
$record->data = $rdata;
173181

174-
$message->answer[] = $record;
182+
$message->answers[] = $record;
175183

176184
return $message;
177185
}

Resolver.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace React\Dns;
44

5+
use React\Dns\Model\Message;
56
use React\Socket\Connection;
67

78
class Resolver
@@ -12,7 +13,7 @@ public function resolve($domain, $callback)
1213
$query = new Query($domain, 'A', 'IN');
1314

1415
$this->query($nameserver, $query, function (Message $response) use ($callback) {
15-
$answer = $response->answer[array_rand($response->answer)]->data->address;
16+
$answer = $response->answers[array_rand($response->answers)]->data;
1617
$callback($address);
1718
});
1819
}
@@ -22,13 +23,10 @@ public function query($nameserver, Query $query, $callback)
2223
$dumper = new BinaryDumper();
2324
$parser = new Parser();
2425

25-
$message = new Message();
26-
$message->header = array(
27-
// $query...
28-
);
29-
$message->question = array(
30-
// $query...
31-
);
26+
$request = new Message();
27+
$request->headers->set('id', rand());
28+
$request->headers->set('rd', 1);
29+
$request->question = (array) $query;
3230

3331
$response = new Message();
3432

@@ -39,6 +37,6 @@ public function query($nameserver, Query $query, $callback)
3937
$callback($response);
4038
}
4139
});
42-
$conn->write($dumper->toBinary($message));
40+
$conn->write($dumper->toBinary($request));
4341
}
4442
}

0 commit comments

Comments
 (0)