+ rr-X -> resource-record-X
+ removed separate cache mapping IPs to FQDNs
This commit is contained in:
parent
a4f7e6f337
commit
e2697605f6
|
@ -377,14 +377,14 @@
|
||||||
;; filters types in a list of rrs
|
;; filters types in a list of rrs
|
||||||
(define (filter-type list type)
|
(define (filter-type list type)
|
||||||
(filter (lambda (rr)
|
(filter (lambda (rr)
|
||||||
(eq? (rr-type rr) type))
|
(eq? (resource-record-type rr) type))
|
||||||
list))
|
list))
|
||||||
|
|
||||||
;; sorts a mx-rr-list by preference. needed for dns-lookup-mail-exchanger.
|
;; sorts a mx-resource-record-list by preference. needed for dns-lookup-mail-exchanger.
|
||||||
(define (sort-by-preference mx-list)
|
(define (sort-by-preference mx-list)
|
||||||
(sort-list mx-list
|
(sort-list mx-list
|
||||||
(lambda (a b)
|
(lambda (a b)
|
||||||
(< (rr-data-mx-preference (rr-data a)) (rr-data-mx-preference (rr-data b))))))
|
(< (resource-record-data-mx-preference (resource-record-data a)) (resource-record-data-mx-preference (resource-record-data b))))))
|
||||||
|
|
||||||
|
|
||||||
;; returns a IP if available (additonal type-a processing)
|
;; returns a IP if available (additonal type-a processing)
|
||||||
|
@ -422,16 +422,17 @@
|
||||||
|
|
||||||
;; makes a query-message (header and question only)
|
;; makes a query-message (header and question only)
|
||||||
;; TODO does this really work for several questions as well?
|
;; TODO does this really work for several questions as well?
|
||||||
(define (make-query-dns-message header . questions)
|
(define (make-query-message header question . questions)
|
||||||
(make-message header questions '() '() '()
|
(let ((questions (cons question questions)))
|
||||||
(apply
|
(make-message header questions '() '() '()
|
||||||
append
|
(apply
|
||||||
(header->octets header)
|
append
|
||||||
(map question->octets questions))))
|
(header->octets header)
|
||||||
|
(map question->octets questions)))))
|
||||||
|
|
||||||
(define (make-simple-query-dns-message id name type class)
|
(define (make-simple-query-message name type class)
|
||||||
(make-query-dns-message (make-std-query-header id 1)
|
(make-query-message (make-std-query-header (random 256) 1)
|
||||||
(make-question name type class)))
|
(make-question name type class)))
|
||||||
|
|
||||||
;; makes a resource record for ans, nss, ars (name, type, class, ttl, data)
|
;; makes a resource record for ans, nss, ars (name, type, class, ttl, data)
|
||||||
(define (make-octet-rr name type class ttl rdata)
|
(define (make-octet-rr name type class ttl rdata)
|
||||||
|
@ -566,15 +567,15 @@
|
||||||
(message-class-number (question-class q)))))
|
(message-class-number (question-class q)))))
|
||||||
(append qname qtype qclass)))
|
(append qname qtype qclass)))
|
||||||
|
|
||||||
;;type rr
|
;;type resource-record
|
||||||
(define-record-type rr :rr
|
(define-record-type resource-record :resource-record
|
||||||
(make-rr name type class ttl data)
|
(make-resource-record name type class ttl data)
|
||||||
rr?
|
resource-record?
|
||||||
(name rr-name)
|
(name resource-record-name)
|
||||||
(type rr-type)
|
(type resource-record-type)
|
||||||
(class rr-class)
|
(class resource-record-class)
|
||||||
(ttl rr-ttl)
|
(ttl resource-record-ttl)
|
||||||
(data rr-data))
|
(data resource-record-data))
|
||||||
|
|
||||||
;; cache
|
;; cache
|
||||||
(define-record-type cache :cache
|
(define-record-type cache :cache
|
||||||
|
@ -654,94 +655,94 @@
|
||||||
(start start)
|
(start start)
|
||||||
(accum '()))
|
(accum '()))
|
||||||
(if (zero? len)
|
(if (zero? len)
|
||||||
(values (make-rr name type class ttl (parse-rr-data type class (reverse! accum) message)) start)
|
(values (make-resource-record name type class ttl (parse-resource-record-data type class (reverse! accum) message)) start)
|
||||||
(loop (- len 1)
|
(loop (- len 1)
|
||||||
(cdr start)
|
(cdr start)
|
||||||
(cons (car start) accum)))))))))))
|
(cons (car start) accum)))))))))))
|
||||||
|
|
||||||
;;; -- rr-data-type records
|
;;; -- resource-record-data-type records
|
||||||
|
|
||||||
(define-record-type rr-data-a :rr-data-a
|
(define-record-type resource-record-data-a :resource-record-data-a
|
||||||
(make-rr-data-a ip)
|
(make-resource-record-data-a ip)
|
||||||
rr-data-a?
|
resource-record-data-a?
|
||||||
(ip rr-data-a-ip))
|
(ip resource-record-data-a-ip))
|
||||||
|
|
||||||
(define-record-type rr-data-ns :rr-data-ns
|
(define-record-type resource-record-data-ns :resource-record-data-ns
|
||||||
(make-rr-data-ns name)
|
(make-resource-record-data-ns name)
|
||||||
rr-data-ns?
|
resource-record-data-ns?
|
||||||
(name rr-data-ns-name))
|
(name resource-record-data-ns-name))
|
||||||
|
|
||||||
(define-record-type rr-data-cname :rr-data-cname
|
(define-record-type resource-record-data-cname :resource-record-data-cname
|
||||||
(make-rr-data-cname name)
|
(make-resource-record-data-cname name)
|
||||||
rr-data-cname?
|
resource-record-data-cname?
|
||||||
(name rr-data-cname-name))
|
(name resource-record-data-cname-name))
|
||||||
|
|
||||||
;; ###
|
;; ###
|
||||||
;; hinfo not correctly implemented, trying to find examples
|
;; hinfo not correctly implemented, trying to find examples
|
||||||
(define-record-type rr-data-hinfo :rr-data-hinfo
|
(define-record-type resource-record-data-hinfo :resource-record-data-hinfo
|
||||||
(make-rr-data-hinfo data)
|
(make-resource-record-data-hinfo data)
|
||||||
rr-data-hinfo?
|
resource-record-data-hinfo?
|
||||||
(data rr-data-hinfo-data))
|
(data resource-record-data-hinfo-data))
|
||||||
|
|
||||||
(define-record-type rr-data-mx :rr-data-mx
|
(define-record-type resource-record-data-mx :resource-record-data-mx
|
||||||
(make-rr-data-mx preference exchanger)
|
(make-resource-record-data-mx preference exchanger)
|
||||||
rr-data-mx?
|
resource-record-data-mx?
|
||||||
(preference rr-data-mx-preference)
|
(preference resource-record-data-mx-preference)
|
||||||
(exchanger rr-data-mx-exchanger))
|
(exchanger resource-record-data-mx-exchanger))
|
||||||
|
|
||||||
(define-record-type rr-data-ptr :rr-data-ptr
|
(define-record-type resource-record-data-ptr :resource-record-data-ptr
|
||||||
(make-rr-data-ptr name)
|
(make-resource-record-data-ptr name)
|
||||||
rr-data-ptr?
|
resource-record-data-ptr?
|
||||||
(name rr-data-ptr-name))
|
(name resource-record-data-ptr-name))
|
||||||
|
|
||||||
(define-record-type rr-data-soa :rr-data-soa
|
(define-record-type resource-record-data-soa :resource-record-data-soa
|
||||||
(make-rr-data-soa mname rname serial refresh retry expire minimum)
|
(make-resource-record-data-soa mname rname serial refresh retry expire minimum)
|
||||||
rr-data-soa?
|
resource-record-data-soa?
|
||||||
(mname rr-data-soa-mname)
|
(mname resource-record-data-soa-mname)
|
||||||
(rname rr-data-soa-rname)
|
(rname resource-record-data-soa-rname)
|
||||||
(serial rr-data-soa-serial)
|
(serial resource-record-data-soa-serial)
|
||||||
(refresh rr-data-soa-refresh)
|
(refresh resource-record-data-soa-refresh)
|
||||||
(retry rr-data-soa-retry)
|
(retry resource-record-data-soa-retry)
|
||||||
(expire rr-data-soa-expire)
|
(expire resource-record-data-soa-expire)
|
||||||
(minimum rr-data-soa-minimum))
|
(minimum resource-record-data-soa-minimum))
|
||||||
|
|
||||||
;; ### same as hinfo
|
;; ### same as hinfo
|
||||||
(define-record-type rr-data-txt :rr-data-txt
|
(define-record-type resource-record-data-txt :resource-record-data-txt
|
||||||
(make-rr-data-txt text)
|
(make-resource-record-data-txt text)
|
||||||
rr-data-txt?
|
resource-record-data-txt?
|
||||||
(text rr-data-txt-text))
|
(text resource-record-data-txt-text))
|
||||||
|
|
||||||
;; ### same as hinfo and txt
|
;; ### same as hinfo and txt
|
||||||
(define-record-type rr-data-wks :rr-data-wks
|
(define-record-type resource-record-data-wks :resource-record-data-wks
|
||||||
(make-rr-data-wks data)
|
(make-resource-record-data-wks data)
|
||||||
rr-data-wks?
|
resource-record-data-wks?
|
||||||
(data rr-data-wks-data))
|
(data resource-record-data-wks-data))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(define (parse-rr-data type class data message)
|
(define (parse-resource-record-data type class data message)
|
||||||
(cond
|
(cond
|
||||||
((eq? type (message-type a))
|
((eq? type (message-type a))
|
||||||
(make-rr-data-a (octet-ip->address32 data)))
|
(make-resource-record-data-a (octet-ip->address32 data)))
|
||||||
|
|
||||||
((eq? type (message-type ns))
|
((eq? type (message-type ns))
|
||||||
(make-rr-data-ns (call-with-values
|
(make-resource-record-data-ns (call-with-values
|
||||||
(lambda () (parse-name data message))
|
(lambda () (parse-name data message))
|
||||||
(lambda (name rest) name))))
|
(lambda (name rest) name))))
|
||||||
|
|
||||||
((eq? type (message-type cname))
|
((eq? type (message-type cname))
|
||||||
(make-rr-data-cname (call-with-values
|
(make-resource-record-data-cname (call-with-values
|
||||||
(lambda () (parse-name data message))
|
(lambda () (parse-name data message))
|
||||||
(lambda (name rest) name))))
|
(lambda (name rest) name))))
|
||||||
|
|
||||||
((eq? type (message-type mx))
|
((eq? type (message-type mx))
|
||||||
(make-rr-data-mx (octet-pair->number (car data) (cadr data))
|
(make-resource-record-data-mx (octet-pair->number (car data) (cadr data))
|
||||||
(call-with-values
|
(call-with-values
|
||||||
(lambda ()(parse-name (cddr data) message))
|
(lambda ()(parse-name (cddr data) message))
|
||||||
(lambda (name rest) name))))
|
(lambda (name rest) name))))
|
||||||
|
|
||||||
((eq? type (message-type ptr))
|
((eq? type (message-type ptr))
|
||||||
(make-rr-data-ptr (call-with-values
|
(make-resource-record-data-ptr (call-with-values
|
||||||
(lambda () (parse-name data message))
|
(lambda () (parse-name data message))
|
||||||
(lambda (name rest) name))))
|
(lambda (name rest) name))))
|
||||||
|
|
||||||
|
@ -762,16 +763,16 @@
|
||||||
(rest (cddddr rest)))
|
(rest (cddddr rest)))
|
||||||
(let ((minimum (octet-quad->number (car rest) (cadr rest) (caddr rest) (cadddr rest)))
|
(let ((minimum (octet-quad->number (car rest) (cadr rest) (caddr rest) (cadddr rest)))
|
||||||
(rest (cddddr rest)))
|
(rest (cddddr rest)))
|
||||||
(make-rr-data-soa mname rname serial refresh retry expire minimum)))))))))))
|
(make-resource-record-data-soa mname rname serial refresh retry expire minimum)))))))))))
|
||||||
|
|
||||||
((eq? type (message-type hinfo))
|
((eq? type (message-type hinfo))
|
||||||
(make-rr-data-hinfo (list->string data)))
|
(make-resource-record-data-hinfo (list->string data)))
|
||||||
|
|
||||||
((eq? type (message-type txt))
|
((eq? type (message-type txt))
|
||||||
(make-rr-data-txt (list->string data)))
|
(make-resource-record-data-txt (list->string data)))
|
||||||
|
|
||||||
((eq? type (message-type wks))
|
((eq? type (message-type wks))
|
||||||
(make-rr-data-wks data))
|
(make-resource-record-data-wks data))
|
||||||
|
|
||||||
(else (list data))))
|
(else (list data))))
|
||||||
|
|
||||||
|
@ -875,10 +876,10 @@
|
||||||
(sock (cdr (assoc w wport-socket-alist))))
|
(sock (cdr (assoc w wport-socket-alist))))
|
||||||
(if (not (connect-socket-successful? sock))
|
(if (not (connect-socket-successful? sock))
|
||||||
(dns-error 'bad-nameserver hit-ns))
|
(dns-error 'bad-nameserver hit-ns))
|
||||||
(let ((query-string
|
(let ((query-string
|
||||||
(add-size-tag (list->string (message-source query))))
|
(list->string (add-size-tag (message-source query))))
|
||||||
(r (socket:inport sock)))
|
(r (socket:inport sock)))
|
||||||
(display (list->string query-string) w)
|
(display query-string w)
|
||||||
(force-output w)
|
(force-output w)
|
||||||
(let ((a (read-char r))
|
(let ((a (read-char r))
|
||||||
(b (read-char r)))
|
(b (read-char r)))
|
||||||
|
@ -960,12 +961,12 @@
|
||||||
(for-each (lambda (x) (find-shortest-ttl-1 x)) (message-nameservers dns-msg))
|
(for-each (lambda (x) (find-shortest-ttl-1 x)) (message-nameservers dns-msg))
|
||||||
(for-each (lambda (x) (find-shortest-ttl-1 x)) (message-additionals dns-msg))
|
(for-each (lambda (x) (find-shortest-ttl-1 x)) (message-additionals dns-msg))
|
||||||
minimum)
|
minimum)
|
||||||
((rr? dns-msg)
|
((resource-record? dns-msg)
|
||||||
(cond
|
(cond
|
||||||
((not minimum) (set! minimum (rr-ttl dns-msg)))
|
((not minimum) (set! minimum (resource-record-ttl dns-msg)))
|
||||||
(else
|
(else
|
||||||
(if (and (not minimum) (> minimum (rr-ttl dns-msg)))
|
(if (and (not minimum) (> minimum (resource-record-ttl dns-msg)))
|
||||||
(set! minimum (rr-ttl dns-msg))))))))))
|
(set! minimum (resource-record-ttl dns-msg))))))))))
|
||||||
(find-shortest-ttl-1 dns-msg)))
|
(find-shortest-ttl-1 dns-msg)))
|
||||||
|
|
||||||
|
|
||||||
|
@ -1022,10 +1023,17 @@
|
||||||
nameservers)))
|
nameservers)))
|
||||||
(else (lp (cdr ns))))))))
|
(else (lp (cdr ns))))))))
|
||||||
|
|
||||||
|
(define-enumerated-type network-protocol :network-protocol
|
||||||
|
network-protocol?
|
||||||
|
network-protocols
|
||||||
|
network-protocol-name
|
||||||
|
network-protocol-index
|
||||||
|
(udp tcp))
|
||||||
|
|
||||||
(define (send-receive-message nameservers query protocol)
|
(define (send-receive-message nameservers query protocol)
|
||||||
((cond
|
((cond
|
||||||
((eq? protocol 'tcp) send-receive-message-tcp)
|
((eq? protocol (network-protocol tcp)) send-receive-message-tcp)
|
||||||
((eq? protocol 'udp) send-receive-message-udp))
|
((eq? protocol (network-protocol udp)) send-receive-message-udp))
|
||||||
nameservers query))
|
nameservers query))
|
||||||
|
|
||||||
;; makes a dns-query. optional cache-check.
|
;; makes a dns-query. optional cache-check.
|
||||||
|
@ -1042,28 +1050,29 @@
|
||||||
;; this feature is technically optional (RFC 1035).
|
;; this feature is technically optional (RFC 1035).
|
||||||
;; dns-get-information implements the resovler-side recursion.
|
;; dns-get-information implements the resovler-side recursion.
|
||||||
;; it returns a dns-message
|
;; it returns a dns-message
|
||||||
(define (dns-get-information query use-cache? protocol nameservers check-answer)
|
(define (dns-get-information query protocol check-answer . args)
|
||||||
(let lp ((tried '()) (nss nameservers))
|
(receive (nameservers use-cache?) (lookup-optional-args args)
|
||||||
(if (null? nss)
|
(let lp ((tried '()) (nss nameservers))
|
||||||
(dns-error 'bad-address)
|
(if (null? nss)
|
||||||
(receive (dns-msg hit-ns nss-with-no-reply)
|
(dns-error 'bad-address)
|
||||||
(dns-query/cache query use-cache? protocol nss tried)
|
(receive (dns-msg hit-ns nss-with-no-reply)
|
||||||
(if (check-answer dns-msg)
|
(dns-query/cache query use-cache? protocol nss tried)
|
||||||
dns-msg
|
(if (check-answer dns-msg)
|
||||||
(let ((auth? (flags-authoritative? (header-flags
|
dns-msg
|
||||||
(message-header
|
(let ((auth? (flags-authoritative? (header-flags
|
||||||
(dns-message-reply dns-msg))))))
|
(message-header
|
||||||
(if auth?
|
(dns-message-reply dns-msg))))))
|
||||||
(dns-error 'bad-address)
|
(if auth?
|
||||||
;; other nameservers names are found in the nameserver-part,
|
(dns-error 'bad-address)
|
||||||
;; but their ip-adresses are found in the additonal-rrs
|
;; other nameservers names are found in the nameserver-part,
|
||||||
(let ((other-nameservers
|
;; but their ip-adresses are found in the additonal-rrs
|
||||||
(filter (lambda (elem) (eq? (rr-type elem) (message-type a)))
|
(let ((other-nameservers
|
||||||
(message-additionals (dns-message-reply dns-msg)))))
|
(filter (lambda (elem) (eq? (resource-record-type elem) (message-type a)))
|
||||||
(lp (if (not (member hit-ns tried)) (cons hit-ns tried) tried)
|
(message-additionals (dns-message-reply dns-msg)))))
|
||||||
(lset-union equal?
|
(lp (if (not (member hit-ns tried)) (cons hit-ns tried) tried)
|
||||||
nss-with-no-reply
|
(lset-union equal?
|
||||||
(lset-difference equal? other-nameservers tried)))))))))))
|
nss-with-no-reply
|
||||||
|
(lset-difference equal? other-nameservers tried))))))))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Parsing of /etc/resolv.conf
|
;; Parsing of /etc/resolv.conf
|
||||||
|
@ -1241,147 +1250,147 @@
|
||||||
(car ns))))
|
(car ns))))
|
||||||
|
|
||||||
|
|
||||||
;; checks the nameservers argument of the lookup functions.
|
;; computes the nameservers argument of the lookup functions.
|
||||||
;; if a nameserver-name is given and not a nameserver-ip
|
;; if a nameserver-name is given and not a nameserver-ip
|
||||||
;; (dns-lookup-name nameserver) is called.
|
;; (dns-lookup-name nameserver) is called.
|
||||||
(define (check-args args)
|
;; use-cache? defaults to #t
|
||||||
|
(define (lookup-optional-args args)
|
||||||
(if (null? args)
|
(if (null? args)
|
||||||
(map ip-string->address32 (dns-find-nameserver-list))
|
(values (map ip-string->address32 (dns-find-nameserver-list)) #t)
|
||||||
(map (lambda (nameserver)
|
(values
|
||||||
(cond
|
(map (lambda (nameserver)
|
||||||
((address32? nameserver) nameserver)
|
(cond
|
||||||
((ip-string? nameserver) (ip-string->address32 nameserver))
|
((address32? nameserver) nameserver)
|
||||||
(else (map (dns-lookup-name nameserver (dns-find-nameserver-list))))))
|
((ip-string? nameserver) (ip-string->address32 nameserver))
|
||||||
(car args))))
|
(else (map (dns-lookup-name nameserver (dns-find-nameserver-list))))))
|
||||||
|
(car args))
|
||||||
|
(if (null? (cdr args))
|
||||||
|
#t
|
||||||
|
(cadr args)))))
|
||||||
|
|
||||||
;; dns-lookup with more options than dns-lookup-*
|
;; dns-lookup with more options than dns-lookup-*
|
||||||
(define (dns-lookup name type . nameservers)
|
(define (dns-lookup name type . args)
|
||||||
(let* ((maybe-ip-string (if (address32? name)
|
(receive (nameservers use-cache?) (lookup-optional-args args)
|
||||||
(ip-string->in-addr-arpa (address32->ip-string name))
|
(let* ((maybe-ip-string (if (address32? name)
|
||||||
(ip-string->in-addr-arpa name)))
|
(ip-string->in-addr-arpa (address32->ip-string name))
|
||||||
(query (if maybe-ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
|
(ip-string->in-addr-arpa name)))
|
||||||
(make-simple-query-dns-message
|
(query (if maybe-ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
|
||||||
(random 256) maybe-ip-string type (message-class in))
|
(make-simple-query-message
|
||||||
(make-simple-query-dns-message (random 256) name type (message-class in))))
|
maybe-ip-string type (message-class in))
|
||||||
(use-cache? #t)
|
(make-simple-query-message name type (message-class in))))
|
||||||
(protocol 'udp)
|
(protocol (network-protocol udp))
|
||||||
(nameservers (check-args nameservers))
|
(check-answer (lambda (dns-msg) #t))
|
||||||
(check-answer (lambda (dns-msg) #t))
|
(dns-msg (dns-get-information query protocol check-answer nameservers use-cache?))
|
||||||
(dns-msg (dns-get-information query use-cache? protocol nameservers check-answer))
|
(answers (message-answers (dns-message-reply dns-msg))))
|
||||||
(answers (message-answers (dns-message-reply dns-msg))))
|
dns-msg)))
|
||||||
dns-msg))
|
|
||||||
|
|
||||||
|
|
||||||
;; looks up a hostname, returns an ip.
|
;; looks up a hostname, returns an ip.
|
||||||
;; (dns-lookup-name <name> nameservers)
|
;; (dns-lookup-name <name> nameservers)
|
||||||
(define (dns-lookup-name name . nameservers)
|
(define (dns-lookup-name name . args)
|
||||||
(let* ((maybe-ip-string (if (address32? name)
|
(receive (nameservers use-cache?) (lookup-optional-args args)
|
||||||
(ip-string->in-addr-arpa (address32->ip-string name))
|
(let* ((maybe-ip-string (if (address32? name)
|
||||||
(ip-string->in-addr-arpa name)))
|
(ip-string->in-addr-arpa (address32->ip-string name))
|
||||||
(query (if maybe-ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
|
(ip-string->in-addr-arpa name)))
|
||||||
(dns-error 'not-a-hostname)
|
(query (if maybe-ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
|
||||||
(make-simple-query-dns-message (random 256) name (message-type a) (message-class in))))
|
(dns-error 'not-a-hostname)
|
||||||
(use-cache? #t)
|
(make-simple-query-message name (message-type a) (message-class in))))
|
||||||
(protocol 'udp)
|
(protocol (network-protocol udp))
|
||||||
(nameservers (check-args nameservers))
|
(check-answer (lambda (dns-msg)
|
||||||
(check-answer (lambda (dns-msg)
|
(let* ((reply (dns-message-reply dns-msg))
|
||||||
(let* ((reply (dns-message-reply dns-msg))
|
(answers (message-answers reply)))
|
||||||
(answers (message-answers reply)))
|
(not (null? (filter-type answers (message-type a)))))))
|
||||||
(not (null? (filter-type answers (message-type a)))))))
|
(dns-msg (dns-get-information query protocol check-answer nameservers use-cache?))
|
||||||
(dns-msg (dns-get-information query use-cache? protocol nameservers check-answer))
|
(answers (filter-type (message-answers (dns-message-reply dns-msg)) (message-type a))))
|
||||||
(answers (filter-type (message-answers (dns-message-reply dns-msg)) (message-type a))))
|
(resource-record-data-a-ip (resource-record-data (car answers))))))
|
||||||
(rr-data-a-ip (rr-data (car answers)))))
|
|
||||||
|
|
||||||
;; looks up an ip, returns a hostname
|
;; looks up an ip, returns a hostname
|
||||||
;; (dns-inverse-lookup <name> [nameserver])
|
;; (dns-inverse-lookup <name> [nameserver])
|
||||||
(define (dns-lookup-ip ip . nameservers)
|
(define (dns-lookup-ip ip . args)
|
||||||
(let* ((maybe-ip-string (if (address32? ip)
|
(receive (nameservers use-cache?) (lookup-optional-args args)
|
||||||
(ip-string->in-addr-arpa (address32->ip-string ip))
|
(let* ((maybe-ip-string (if (address32? ip)
|
||||||
(ip-string->in-addr-arpa ip)))
|
(ip-string->in-addr-arpa (address32->ip-string ip))
|
||||||
(query (if maybe-ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
|
(ip-string->in-addr-arpa ip)))
|
||||||
(make-simple-query-dns-message (random 256) maybe-ip-string (message-type ptr) (message-class in))
|
(query (if maybe-ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
|
||||||
(dns-error 'not-a-ip)))
|
(make-simple-query-message maybe-ip-string (message-type ptr) (message-class in))
|
||||||
(use-cache? #t)
|
(dns-error 'not-a-ip)))
|
||||||
(protocol 'udp)
|
(protocol (network-protocol udp))
|
||||||
(nameservers (check-args nameservers))
|
(check-answer (lambda (dns-msg)
|
||||||
(check-answer (lambda (dns-msg)
|
(let* ((reply (dns-message-reply dns-msg))
|
||||||
(let* ((reply (dns-message-reply dns-msg))
|
(answers (message-answers reply)))
|
||||||
(answers (message-answers reply)))
|
(not (null? (filter-type answers (message-type ptr)))))))
|
||||||
(not (null? (filter-type answers (message-type ptr)))))))
|
(dns-msg (dns-get-information query protocol check-answer nameservers use-cache?))
|
||||||
(dns-msg (dns-get-information query use-cache? protocol nameservers check-answer))
|
(answers (filter-type (message-answers (dns-message-reply dns-msg)) (message-type ptr))))
|
||||||
(answers (filter-type (message-answers (dns-message-reply dns-msg)) (message-type ptr))))
|
(resource-record-data-ptr-name (resource-record-data (car answers))))))
|
||||||
(rr-data-ptr-name (rr-data (car answers)))))
|
|
||||||
|
|
||||||
(define dns-inverse-lookup dns-lookup-ip)
|
(define dns-inverse-lookup dns-lookup-ip)
|
||||||
|
|
||||||
;; looks up an authoritative nameserver for a hostname
|
;; looks up an authoritative nameserver for a hostname
|
||||||
;; returns a list of nameservers
|
;; returns a list of nameservers
|
||||||
;; (dns-lookup-nameserver <name> [nameserver])
|
;; (dns-lookup-nameserver <name> [nameserver])
|
||||||
(define (dns-lookup-nameserver name . nameservers)
|
(define (dns-lookup-nameserver name . args)
|
||||||
(let* ((maybe-ip-string (if (address32? name)
|
(receive (nameservers use-cache?) (lookup-optional-args args)
|
||||||
(ip-string->in-addr-arpa (address32->ip-string name))
|
(let* ((maybe-ip-string (if (address32? name)
|
||||||
(ip-string->in-addr-arpa name)))
|
(ip-string->in-addr-arpa (address32->ip-string name))
|
||||||
(query (if maybe-ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
|
(ip-string->in-addr-arpa name)))
|
||||||
(dns-error 'not-a-hostname)
|
(query (if maybe-ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
|
||||||
(make-simple-query-dns-message
|
(dns-error 'not-a-hostname)
|
||||||
(random 256) name (message-type ns) (message-class in))))
|
(make-simple-query-message
|
||||||
(use-cache? #t)
|
name (message-type ns) (message-class in))))
|
||||||
(protocol 'udp)
|
(protocol (network-protocol udp))
|
||||||
(nameservers (check-args nameservers))
|
(check-answer (lambda (dns-msg)
|
||||||
(check-answer (lambda (dns-msg)
|
(let* ((reply (dns-message-reply dns-msg))
|
||||||
(let* ((reply (dns-message-reply dns-msg))
|
(answers (message-answers reply))
|
||||||
(answers (message-answers reply))
|
(nameservers (message-nameservers reply)))
|
||||||
(nameservers (message-nameservers reply)))
|
(or (not (null? (filter-type nameservers (message-type soa))))
|
||||||
(or (not (null? (filter-type nameservers (message-type soa))))
|
(not (null? (filter-type answers (message-type ns))))))))
|
||||||
(not (null? (filter-type answers (message-type ns))))))))
|
(dns-msg (dns-get-information query protocol check-answer nameservers use-cache?))
|
||||||
(dns-msg (dns-get-information query use-cache? protocol nameservers check-answer))
|
(reply (dns-message-reply dns-msg))
|
||||||
(reply (dns-message-reply dns-msg))
|
(soa (filter-type (message-nameservers reply) (message-type soa)))
|
||||||
(soa (filter-type (message-nameservers reply) (message-type soa)))
|
(nss (filter-type (message-answers reply) (message-type ns)))
|
||||||
(nss (filter-type (message-answers reply) (message-type ns)))
|
(add (filter-type (message-additionals reply) (message-type a))))
|
||||||
(add (filter-type (message-additionals reply) (message-type a))))
|
(if (null? nss)
|
||||||
(if (null? nss)
|
(list (dns-lookup-name (resource-record-data-soa-mname (resource-record-data (car soa)))))
|
||||||
(list (dns-lookup-name (rr-data-soa-mname (rr-data (car soa)))))
|
(map (lambda (elem) (resource-record-data-a-ip (resource-record-data elem))) add)))))
|
||||||
(map (lambda (elem) (rr-data-a-ip (rr-data elem))) add))))
|
|
||||||
|
|
||||||
;; looks up a mail-exchanger for a hostname.
|
;; looks up a mail-exchanger for a hostname.
|
||||||
;; returns a list of mail-exchanger, sorted by their preference
|
;; returns a list of mail-exchanger, sorted by their preference
|
||||||
;; if there are no mx-records in the answer-section,
|
;; if there are no mx-records in the answer-section,
|
||||||
;; implementation based on RFC2821
|
;; implementation based on RFC2821
|
||||||
;; (dns-lookup-mail-exchanger <name> [nameserver])
|
;; (dns-lookup-mail-exchanger <name> [nameserver])
|
||||||
(define (dns-lookup-mail-exchanger name . nameservers)
|
(define (dns-lookup-mail-exchanger name . args)
|
||||||
(let* ((ip-string (if (address32? name)
|
(receive (nameservers use-cache?) (lookup-optional-args args)
|
||||||
(ip-string->in-addr-arpa (address32->ip-string name))
|
(let* ((ip-string (if (address32? name)
|
||||||
(ip-string->in-addr-arpa name)))
|
(ip-string->in-addr-arpa (address32->ip-string name))
|
||||||
(query (if ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
|
(ip-string->in-addr-arpa name)))
|
||||||
(dns-error 'not-a-hostname)
|
(query (if ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
|
||||||
(make-simple-query-dns-message
|
(dns-error 'not-a-hostname)
|
||||||
(random 256) name (message-type mx) (message-class in))))
|
(make-simple-query-message
|
||||||
(use-cache? #t)
|
name (message-type mx) (message-class in))))
|
||||||
(protocol 'tcp)
|
(protocol (network-protocol tcp))
|
||||||
(nameservers (check-args nameservers))
|
(check-answer (lambda (dns-msg)
|
||||||
(check-answer (lambda (dns-msg)
|
(let* ((reply (dns-message-reply dns-msg))
|
||||||
(let* ((reply (dns-message-reply dns-msg))
|
(answers (message-answers reply))
|
||||||
(answers (message-answers reply))
|
(nameservers (message-nameservers reply)))
|
||||||
(nameservers (message-nameservers reply)))
|
(or (not (null? (filter-type answers (message-type mx))))
|
||||||
(or (not (null? (filter-type answers (message-type mx))))
|
(not (null? (filter-type answers (message-type cname))))
|
||||||
(not (null? (filter-type answers (message-type cname))))
|
(not (null? (filter-type answers (message-type a))))))))
|
||||||
(not (null? (filter-type answers (message-type a))))))))
|
(dns-msg (dns-get-information query protocol check-answer nameservers use-cache?))
|
||||||
(dns-msg (dns-get-information query use-cache? protocol nameservers check-answer))
|
(reply (dns-message-reply dns-msg))
|
||||||
(reply (dns-message-reply dns-msg))
|
(mx (filter-type (message-answers reply) (message-type mx)))
|
||||||
(mx (filter-type (message-answers reply) (message-type mx)))
|
(soa (filter-type (message-nameservers reply)(message-type soa)))
|
||||||
(soa (filter-type (message-nameservers reply)(message-type soa)))
|
(cname (filter-type (message-answers reply) (message-type cname)))
|
||||||
(cname (filter-type (message-answers reply) (message-type cname)))
|
(a (filter-type (message-answers reply) (message-type a))))
|
||||||
(a (filter-type (message-answers reply) (message-type a))))
|
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
((not (null? a))
|
((not (null? a))
|
||||||
(list (rr-data-a-ip (rr-data (car a)))))
|
(list (resource-record-data-a-ip (resource-record-data (car a)))))
|
||||||
((not (null? cname))
|
((not (null? cname))
|
||||||
(dns-lookup-mail-exchanger (rr-data-cname-name (rr-data (car cname)))))
|
(dns-lookup-mail-exchanger (resource-record-data-cname-name (resource-record-data (car cname)))))
|
||||||
((null? mx)
|
((null? mx)
|
||||||
(list (rr-data-soa-rname (rr-data (car soa)))))
|
(list (resource-record-data-soa-rname (resource-record-data (car soa)))))
|
||||||
(else
|
(else
|
||||||
(map (lambda (elem) (rr-data-mx-exchanger (rr-data elem))) (sort-by-preference mx))))))
|
(map (lambda (elem) (resource-record-data-mx-exchanger (resource-record-data elem))) (sort-by-preference mx)))))))
|
||||||
|
|
||||||
;;; pretty-prints a dns-msg
|
;;; pretty-prints a dns-msg
|
||||||
(define (pretty-print-dns-message dns-msg . maybe-port)
|
(define (pretty-print-dns-message dns-msg . maybe-port)
|
||||||
|
@ -1413,8 +1422,8 @@
|
||||||
"not found in cache"))
|
"not found in cache"))
|
||||||
(d 1 "PROTOCOL" (let ((protocol (dns-message-protocol dns-msg)))
|
(d 1 "PROTOCOL" (let ((protocol (dns-message-protocol dns-msg)))
|
||||||
(cond
|
(cond
|
||||||
((eq? protocol 'tcp) "TCP")
|
((eq? protocol (network-protocol tcp)) "TCP")
|
||||||
((eq? protocol 'udp) "UDP"))))
|
((eq? protocol (network-protocol udp)) "UDP"))))
|
||||||
(d 1 "TRIED-NAMESERVERS" (if (> (length (dns-message-tried-nameservers dns-msg)) 1)
|
(d 1 "TRIED-NAMESERVERS" (if (> (length (dns-message-tried-nameservers dns-msg)) 1)
|
||||||
(begin
|
(begin
|
||||||
(display " had perform recursion: ")
|
(display " had perform recursion: ")
|
||||||
|
@ -1453,73 +1462,52 @@
|
||||||
(d 4 "name " (question-name dns-msg))
|
(d 4 "name " (question-name dns-msg))
|
||||||
(d 4 "type " (message-type-name (question-type dns-msg)))
|
(d 4 "type " (message-type-name (question-type dns-msg)))
|
||||||
(d 4 "class" (message-class-name (question-class dns-msg)))))
|
(d 4 "class" (message-class-name (question-class dns-msg)))))
|
||||||
((rr? dns-msg)
|
((resource-record? dns-msg)
|
||||||
(begin
|
(begin
|
||||||
(d 4 "name " (rr-name dns-msg))
|
(d 4 "name " (resource-record-name dns-msg))
|
||||||
(d 4 "type "(message-type-name (rr-type dns-msg)))
|
(d 4 "type "(message-type-name (resource-record-type dns-msg)))
|
||||||
(d 4 "class" (message-class-name (rr-class dns-msg)))
|
(d 4 "class" (message-class-name (resource-record-class dns-msg)))
|
||||||
(d 4 "ttl " (rr-ttl dns-msg))
|
(d 4 "ttl " (resource-record-ttl dns-msg))
|
||||||
(d 4 "data " "") (show-dns-message (rr-data dns-msg))))
|
(d 4 "data " "") (show-dns-message (resource-record-data dns-msg))))
|
||||||
((rr-data-a? dns-msg)
|
((resource-record-data-a? dns-msg)
|
||||||
(d 5 "ip " (rr-data-a-ip dns-msg)))
|
(d 5 "ip " (resource-record-data-a-ip dns-msg)))
|
||||||
((rr-data-ns? dns-msg)
|
((resource-record-data-ns? dns-msg)
|
||||||
(d 5 "name " (rr-data-ns-name dns-msg)))
|
(d 5 "name " (resource-record-data-ns-name dns-msg)))
|
||||||
((rr-data-cname? dns-msg)
|
((resource-record-data-cname? dns-msg)
|
||||||
(d 5 "name " (rr-data-cname-name dns-msg)))
|
(d 5 "name " (resource-record-data-cname-name dns-msg)))
|
||||||
((rr-data-mx? dns-msg)
|
((resource-record-data-mx? dns-msg)
|
||||||
(begin
|
(begin
|
||||||
(d 5 "preference " (rr-data-mx-preference dns-msg))
|
(d 5 "preference " (resource-record-data-mx-preference dns-msg))
|
||||||
(d 5 "exchanger " (rr-data-mx-exchanger dns-msg))))
|
(d 5 "exchanger " (resource-record-data-mx-exchanger dns-msg))))
|
||||||
((rr-data-ptr? dns-msg)
|
((resource-record-data-ptr? dns-msg)
|
||||||
(d 5 "name " (rr-data-ptr-name dns-msg)))
|
(d 5 "name " (resource-record-data-ptr-name dns-msg)))
|
||||||
((rr-data-soa? dns-msg)
|
((resource-record-data-soa? dns-msg)
|
||||||
(begin
|
(begin
|
||||||
(d 5 "mname " (rr-data-soa-mname dns-msg))
|
(d 5 "mname " (resource-record-data-soa-mname dns-msg))
|
||||||
(d 5 "rname " (rr-data-soa-rname dns-msg))
|
(d 5 "rname " (resource-record-data-soa-rname dns-msg))
|
||||||
(d 5 "serial " (rr-data-soa-serial dns-msg))
|
(d 5 "serial " (resource-record-data-soa-serial dns-msg))
|
||||||
(d 5 "refresh " (rr-data-soa-refresh dns-msg))
|
(d 5 "refresh " (resource-record-data-soa-refresh dns-msg))
|
||||||
(d 5 "expire " (rr-data-soa-expire dns-msg))
|
(d 5 "expire " (resource-record-data-soa-expire dns-msg))
|
||||||
(d 5 "minimum " (rr-data-soa-expire dns-msg))))
|
(d 5 "minimum " (resource-record-data-soa-expire dns-msg))))
|
||||||
;; ###
|
;; ###
|
||||||
((rr-data-hinfo? dns-msg)
|
((resource-record-data-hinfo? dns-msg)
|
||||||
(d 5 "data " (rr-data-hinfo-data dns-msg)))
|
(d 5 "data " (resource-record-data-hinfo-data dns-msg)))
|
||||||
((rr-data-txt? dns-msg)
|
((resource-record-data-txt? dns-msg)
|
||||||
(d 5 "text " (rr-data-txt-text dns-msg)))
|
(d 5 "text " (resource-record-data-txt-text dns-msg)))
|
||||||
((rr-data-wks? dns-msg)
|
((resource-record-data-wks? dns-msg)
|
||||||
(d 5 "data " (rr-data-wks-data dns-msg)))
|
(d 5 "data " (resource-record-data-wks-data dns-msg)))
|
||||||
))
|
))
|
||||||
(show-dns-message dns-msg)))))
|
(show-dns-message dns-msg)))))
|
||||||
|
|
||||||
(define *fqdn-lock* (make-lock))
|
(define (socket-address->fqdn addr . args)
|
||||||
(define *fqdn-cache* '())
|
|
||||||
|
|
||||||
(define (socket-address->fqdn addr cache?)
|
|
||||||
(receive (ip32 port)
|
(receive (ip32 port)
|
||||||
(socket-address->internet-address addr)
|
(socket-address->internet-address addr)
|
||||||
(internet-address->fqdn ip32 cache?)))
|
(apply dns-lookup-ip ip32 args)))
|
||||||
|
|
||||||
(define (internet-address->fqdn ip32 cache?)
|
(define (fqdn? name)
|
||||||
(if cache?
|
|
||||||
(begin
|
|
||||||
(obtain-lock *fqdn-lock*)
|
|
||||||
(cond
|
|
||||||
((assv ip32 *fqdn-cache*) =>
|
|
||||||
(lambda (pair)
|
|
||||||
(release-lock *fqdn-lock*)
|
|
||||||
(cdr pair)))
|
|
||||||
(else
|
|
||||||
(release-lock *fqdn-lock*)
|
|
||||||
(let ((fqdn (dns-lookup-ip ip32)))
|
|
||||||
(set! *fqdn-cache*
|
|
||||||
(cons (cons ip32 fqdn) *fqdn-cache*))
|
|
||||||
fqdn))))
|
|
||||||
(dns-lookup-ip ip32)))
|
|
||||||
|
|
||||||
|
|
||||||
(define (is-fqdn? name)
|
|
||||||
(regexp-search? (rx #\.) name))
|
(regexp-search? (rx #\.) name))
|
||||||
|
|
||||||
(define (maybe-dns-lookup-name name)
|
(define (maybe-dns-lookup-name name . args)
|
||||||
(call-with-current-continuation
|
(call-with-current-continuation
|
||||||
(lambda (k)
|
(lambda (k)
|
||||||
(with-handler (lambda (cond more)
|
(with-handler (lambda (cond more)
|
||||||
|
@ -1527,9 +1515,9 @@
|
||||||
(k #f)
|
(k #f)
|
||||||
(more)))
|
(more)))
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(dns-lookup-name name))))))
|
(dns-lookup-name name args))))))
|
||||||
|
|
||||||
(define (maybe-dns-lookup-ip ip-addr)
|
(define (maybe-dns-lookup-ip ip-addr . args)
|
||||||
(call-with-current-continuation
|
(call-with-current-continuation
|
||||||
(lambda (k)
|
(lambda (k)
|
||||||
(with-handler (lambda (cond more)
|
(with-handler (lambda (cond more)
|
||||||
|
@ -1537,7 +1525,7 @@
|
||||||
(k #f)
|
(k #f)
|
||||||
(more)))
|
(more)))
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(dns-lookup-ip ip-addr))))))
|
(apply dns-lookup-ip ip-addr args))))))
|
||||||
|
|
||||||
(define (domains-for-search)
|
(define (domains-for-search)
|
||||||
(cond ((assoc 'domain (resolv.conf))
|
(cond ((assoc 'domain (resolv.conf))
|
||||||
|
@ -1548,20 +1536,21 @@
|
||||||
(cdr pair)))
|
(cdr pair)))
|
||||||
(else '())))
|
(else '())))
|
||||||
|
|
||||||
(define (host-fqdn name-or-socket-address)
|
(define (host-fqdn name-or-socket-address . args)
|
||||||
(if (socket-address? name-or-socket-address)
|
(if (socket-address? name-or-socket-address)
|
||||||
(socket-address->fqdn name-or-socket-address #f)
|
(apply socket-address->fqdn name-or-socket-address args)
|
||||||
(let ((name name-or-socket-address))
|
(let ((name name-or-socket-address))
|
||||||
(if (is-fqdn? name)
|
(if (is-fqdn? name)
|
||||||
name
|
name
|
||||||
(let lp ((domains (domains-for-search)))
|
(let lp ((domains (domains-for-search)))
|
||||||
(if (null? domains)
|
(if (null? domains)
|
||||||
#f
|
#f
|
||||||
(cond ((maybe-dns-lookup-name (string-append name "." (car domains)))
|
(cond ((apply maybe-dns-lookup-name
|
||||||
|
(string-append name "." (car domains)) args)
|
||||||
=> (lambda (ip)
|
=> (lambda (ip)
|
||||||
(dns-lookup-ip ip)))
|
(apply dns-lookup-ip ip args)))
|
||||||
(else (lp (cdr domains))))))))))
|
(else (lp (cdr domains))))))))))
|
||||||
|
|
||||||
(define (system-fqdn)
|
(define (system-fqdn . args)
|
||||||
(host-fqdn (system-name)))
|
(apply host-fqdn (system-name) args))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue