@@ -26,34 +26,75 @@ public function resolve($domain)
2626
2727 return $ this ->executor
2828 ->query ($ this ->nameserver , $ query )
29- ->then (function (Message $ response ) use ($ that ) {
30- return $ that ->extractAddress ($ response , Message:: TYPE_A );
29+ ->then (function (Message $ response ) use ($ that, $ query ) {
30+ return $ that ->extractAddress ($ query , $ response );
3131 });
3232 }
3333
34- public function extractAddress (Message $ response , $ type )
34+ public function extractAddress (Query $ query , Message $ response )
3535 {
36- $ answer = $ this ->pickRandomAnswerOfType ($ response , $ type );
37- $ address = $ answer ->data ;
36+ $ answers = $ response ->answers ;
37+
38+ $ addresses = $ this ->resolveAliases ($ answers , $ query ->name );
39+
40+ if (0 === count ($ addresses )) {
41+ $ message = 'DNS Request did not return valid answer. ' ;
42+ throw new RecordNotFoundException ($ message );
43+ }
44+
45+ $ address = $ addresses [array_rand ($ addresses )];
3846 return $ address ;
3947 }
4048
41- public function pickRandomAnswerOfType ( Message $ response , $ type )
49+ public function resolveAliases ( array $ answers , $ name )
4250 {
43- // TODO: filter by name to make sure domain matches
44- // TODO: resolve CNAME aliases
51+ $ named = $ this ->filterByName ($ answers , $ name );
52+ $ aRecords = $ this ->filterByType ($ named , Message::TYPE_A );
53+ $ cnameRecords = $ this ->filterByType ($ named , Message::TYPE_CNAME );
4554
46- $ filteredAnswers = array_filter ( $ response -> answers , function ( $ answer ) use ( $ type ) {
47- return $ type === $ answer -> type ;
48- });
55+ if ( $ aRecords ) {
56+ return $ this -> mapRecordData ( $ aRecords ) ;
57+ }
4958
50- if (0 === count ($ filteredAnswers )) {
51- $ message = sprintf ('DNS Request did not return valid answer. Received answers: %s ' , json_encode ($ response ->answers ));
52- throw new RecordNotFoundException ($ message );
59+ if ($ cnameRecords ) {
60+ $ aRecords = array ();
61+
62+ $ cnames = $ this ->mapRecordData ($ cnameRecords );
63+ foreach ($ cnames as $ cname ) {
64+ $ targets = $ this ->filterByName ($ answers , $ cname );
65+ $ aRecords = array_merge (
66+ $ aRecords ,
67+ $ this ->resolveAliases ($ answers , $ cname )
68+ );
69+ }
70+
71+ return $ aRecords ;
5372 }
5473
55- $ answer = $ filteredAnswers [array_rand ($ filteredAnswers )];
74+ return array ();
75+ }
76+
77+ private function filterByName (array $ answers , $ name )
78+ {
79+ return $ this ->filterByField ($ answers , 'name ' , $ name );
80+ }
81+
82+ private function filterByType (array $ answers , $ type )
83+ {
84+ return $ this ->filterByField ($ answers , 'type ' , $ type );
85+ }
5686
57- return $ answer ;
87+ private function filterByField (array $ answers , $ field , $ value )
88+ {
89+ return array_filter ($ answers , function ($ answer ) use ($ field , $ value ) {
90+ return $ value === $ answer ->$ field ;
91+ });
92+ }
93+
94+ private function mapRecordData (array $ records )
95+ {
96+ return array_map (function ($ record ) {
97+ return $ record ->data ;
98+ }, $ records );
5899 }
59100}
0 commit comments