zone.lisp: Memoize the conversion of TLSA association-data files.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 22 Dec 2014 20:32:58 +0000 (20:32 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Tue, 23 Dec 2014 11:57:36 +0000 (11:57 +0000)
zone.lisp

index 1557c0a..a90490a 100644 (file)
--- a/zone.lisp
+++ b/zone.lisp
   "Default pathname components for TLSA records.")
 (pushnew '*tlsa-pathname-defaults* *zone-config*)
 
+(defparameter *tlsa-data-cache* (make-hash-table :test #'equal)
+  "Cache for TLSA association data; keys are (DATA SELECTOR MATCH).")
+
 (defun convert-tlsa-selector-data (data selector match)
   "Convert certificate association DATA as required by SELECTOR and MATCH.
 
                (reverse-enum 'tlsa-match match)))
        bin))
     (pathname
-     (with-temporary-files (context :base (make-pathname :type "tmp"))
-       (let* ((file (or (find-if #'probe-file
-                                (mapcar (lambda (template)
-                                          (merge-pathnames data template))
-                                        *tlsa-pathname-defaults*))
-                        (error "Couldn't find TLSA file `~A'" data)))
-             (kind (identify-tlsa-selector-file file))
-             (raw (raw-tlsa-assoc-data kind selector file context)))
-        (read-tlsa-match-data match raw context))))))
+     (let ((key (list data selector match)))
+       (or (gethash key *tlsa-data-cache*)
+          (with-temporary-files (context :base (make-pathname :type "tmp"))
+            (let* ((file (or (find-if #'probe-file
+                                      (mapcar (lambda (template)
+                                                (merge-pathnames data
+                                                                 template))
+                                              *tlsa-pathname-defaults*))
+                             (error "Couldn't find TLSA file `~A'" data)))
+                   (kind (identify-tlsa-selector-file file))
+                   (raw (raw-tlsa-assoc-data kind selector file context))
+                   (binary (read-tlsa-match-data match raw context)))
+              (setf (gethash key *tlsa-data-cache*) binary))))))))
 
 (defzoneparse :tlsa (name data rec)
   ":tlsa (((SERVICE|PORT &key :protocol)*) (USAGE SELECTOR MATCH DATA)*)"