33namespace React \Dns \Query ;
44
55use React \Dns \Model \Message ;
6+ use React \Dns \Model \Record ;
67
78class CachedExecutor implements ExecutorInterface
89{
@@ -17,16 +18,43 @@ public function __construct(ExecutorInterface $executor, RecordCache $cache)
1718
1819 public function query ($ nameserver , Query $ query , $ callback )
1920 {
20- $ cachedRecord = $ this ->cache ->lookup ($ query );
21- if (null !== $ cachedRecord ) {
22- $ callback ($ cachedRecord );
21+ $ cachedRecords = $ this ->cache ->lookup ($ query );
22+ if (count ($ cachedRecords )) {
23+ $ cachedResponse = $ this ->buildResponse ($ query , $ cachedRecords );
24+ $ callback ($ cachedResponse );
2325 return ;
2426 }
2527
2628 $ cache = $ this ->cache ;
2729 $ this ->executor ->query ($ nameserver , $ query , function ($ response ) use ($ cache , $ query , $ callback ) {
2830 $ callback ($ response );
29- $ cache ->storeResponseMessage ($ response );
31+ $ cache ->storeResponseMessage ($ query -> currentTime , $ response );
3032 });
3133 }
34+
35+ private function buildResponse (Query $ query , array $ cachedRecords )
36+ {
37+ $ response = new Message ();
38+
39+ $ response ->header ->set ('id ' , $ this ->generateId ());
40+ $ response ->header ->set ('qr ' , 1 );
41+ $ response ->header ->set ('opcode ' , Message::OPCODE_QUERY );
42+ $ response ->header ->set ('rd ' , 1 );
43+ $ response ->header ->set ('rcode ' , Message::RCODE_OK );
44+
45+ $ response ->questions [] = new Record ($ query ->name , $ query ->type , $ query ->class );
46+
47+ foreach ($ cachedRecords as $ record ) {
48+ $ response ->answers [] = $ record ;
49+ }
50+
51+ $ response ->prepare ();
52+
53+ return $ response ;
54+ }
55+
56+ protected function generateId ()
57+ {
58+ return mt_rand (0 , 0xffff );
59+ }
3260}
0 commit comments