@@ -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