Skip to content

Commit d6a774b

Browse files
committed
Merge branch 'dns-cname' into 0.4
* dns-cname: Fix @Covers annotation [Dns] Correctly resolve CNAME aliases Conflicts: src/React/Dns/Resolver/Resolver.php
2 parents 849b847 + c38bbdf commit d6a774b

1 file changed

Lines changed: 57 additions & 16 deletions

File tree

Resolver/Resolver.php

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,34 +24,75 @@ public function resolve($domain)
2424

2525
return $this->executor
2626
->query($this->nameserver, $query)
27-
->then(function (Message $response) {
28-
return $this->extractAddress($response, Message::TYPE_A);
27+
->then(function (Message $response) use ($query) {
28+
return $this->extractAddress($query, $response);
2929
});
3030
}
3131

32-
public function extractAddress(Message $response, $type)
32+
public function extractAddress(Query $query, Message $response)
3333
{
34-
$answer = $this->pickRandomAnswerOfType($response, $type);
35-
$address = $answer->data;
34+
$answers = $response->answers;
35+
36+
$addresses = $this->resolveAliases($answers, $query->name);
37+
38+
if (0 === count($addresses)) {
39+
$message = 'DNS Request did not return valid answer.';
40+
throw new RecordNotFoundException($message);
41+
}
42+
43+
$address = $addresses[array_rand($addresses)];
3644
return $address;
3745
}
3846

39-
public function pickRandomAnswerOfType(Message $response, $type)
47+
public function resolveAliases(array $answers, $name)
4048
{
41-
// TODO: filter by name to make sure domain matches
42-
// TODO: resolve CNAME aliases
49+
$named = $this->filterByName($answers, $name);
50+
$aRecords = $this->filterByType($named, Message::TYPE_A);
51+
$cnameRecords = $this->filterByType($named, Message::TYPE_CNAME);
4352

44-
$filteredAnswers = array_filter($response->answers, function ($answer) use ($type) {
45-
return $type === $answer->type;
46-
});
53+
if ($aRecords) {
54+
return $this->mapRecordData($aRecords);
55+
}
4756

48-
if (0 === count($filteredAnswers)) {
49-
$message = sprintf('DNS Request did not return valid answer. Received answers: %s', json_encode($response->answers));
50-
throw new RecordNotFoundException($message);
57+
if ($cnameRecords) {
58+
$aRecords = array();
59+
60+
$cnames = $this->mapRecordData($cnameRecords);
61+
foreach ($cnames as $cname) {
62+
$targets = $this->filterByName($answers, $cname);
63+
$aRecords = array_merge(
64+
$aRecords,
65+
$this->resolveAliases($answers, $cname)
66+
);
67+
}
68+
69+
return $aRecords;
5170
}
5271

53-
$answer = $filteredAnswers[array_rand($filteredAnswers)];
72+
return array();
73+
}
74+
75+
private function filterByName(array $answers, $name)
76+
{
77+
return $this->filterByField($answers, 'name', $name);
78+
}
79+
80+
private function filterByType(array $answers, $type)
81+
{
82+
return $this->filterByField($answers, 'type', $type);
83+
}
5484

55-
return $answer;
85+
private function filterByField(array $answers, $field, $value)
86+
{
87+
return array_filter($answers, function ($answer) use ($field, $value) {
88+
return $value === $answer->$field;
89+
});
90+
}
91+
92+
private function mapRecordData(array $records)
93+
{
94+
return array_map(function ($record) {
95+
return $record->data;
96+
}, $records);
5697
}
5798
}

0 commit comments

Comments
 (0)