99class CachingExecutor implements ExecutorInterface
1010{
1111 /**
12- * Initial implementation uses a fixed TTL for postive DNS responses as well
13- * as negative responses (NXDOMAIN etc.).
12+ * Default TTL for negative responses (NXDOMAIN etc.).
1413 *
1514 * @internal
1615 */
@@ -29,23 +28,24 @@ public function query($nameserver, Query $query)
2928 {
3029 $ id = $ query ->name . ': ' . $ query ->type . ': ' . $ query ->class ;
3130 $ cache = $ this ->cache ;
31+ $ that = $ this ;
3232 $ executor = $ this ->executor ;
3333
3434 $ pending = $ cache ->get ($ id );
35- return new Promise (function ($ resolve , $ reject ) use ($ nameserver , $ query , $ id , $ cache , $ executor , &$ pending ) {
35+ return new Promise (function ($ resolve , $ reject ) use ($ nameserver , $ query , $ id , $ cache , $ executor , &$ pending, $ that ) {
3636 $ pending ->then (
37- function ($ message ) use ($ nameserver , $ query , $ id , $ cache , $ executor , &$ pending ) {
37+ function ($ message ) use ($ nameserver , $ query , $ id , $ cache , $ executor , &$ pending, $ that ) {
3838 // return cached response message on cache hit
3939 if ($ message !== null ) {
4040 return $ message ;
4141 }
4242
4343 // perform DNS lookup if not already cached
4444 return $ pending = $ executor ->query ($ nameserver , $ query )->then (
45- function (Message $ message ) use ($ cache , $ id ) {
45+ function (Message $ message ) use ($ cache , $ id, $ that ) {
4646 // DNS response message received => store in cache when not truncated and return
4747 if (!$ message ->header ->isTruncated ()) {
48- $ cache ->set ($ id , $ message , CachingExecutor:: TTL );
48+ $ cache ->set ($ id , $ message , $ that -> ttl ( $ message ) );
4949 }
5050
5151 return $ message ;
@@ -58,4 +58,27 @@ function (Message $message) use ($cache, $id) {
5858 $ pending ->cancel ();
5959 });
6060 }
61+
62+ /**
63+ * @param Message $message
64+ * @return int
65+ * @internal
66+ */
67+ public function ttl (Message $ message )
68+ {
69+ // select TTL from answers (should all be the same), use smallest value if available
70+ // @link https://tools.ietf.org/html/rfc2181#section-5.2
71+ $ ttl = null ;
72+ foreach ($ message ->answers as $ answer ) {
73+ if ($ ttl === null || $ answer ->ttl < $ ttl ) {
74+ $ ttl = $ answer ->ttl ;
75+ }
76+ }
77+
78+ if ($ ttl === null ) {
79+ $ ttl = self ::TTL ;
80+ }
81+
82+ return $ ttl ;
83+ }
6184}
0 commit comments