IPs are now 32bit integer internet addresses,

changed the API for concurrent-lookup,
revised the documentation
This commit is contained in:
cresh 2002-07-07 17:43:32 +00:00
parent 27ff0f4326
commit 470c2fbab3
2 changed files with 129 additions and 55 deletions

View File

@ -14,31 +14,40 @@
; ---
; sample usage & documentation:
;
; <name>, <ip-string> and <nameserver> are strings.
; <ip-address32> is a 32bit integer internet->address, shortly address32.
; <ip-string> is a string in standard dot notation "xxx.xxx.xxx.xxx".
; <name> is a string
;
; <nameserver> can either be a domainname or a ip.
; <nameserver> can either be a domainname, an ip-string or an ip-address32.
; if it is a domainname, its ip is looked up on a nameserver listed in
; /etc/resolv.conf.
;
; (dns-find-nameserver) --> <ip-string>
; (dns-find-nameserver) --> <ip-address32>
; this parses the /etc/resolv.conf file and returns the first found
; nameserver.
; nameserver in address32 format.
;
;
;
; (dns-lookup-name <name> [nameserver]) --> <ip-string>
; (dns-lookup-ip <ip-string> [nameserver]) --> <name>
; (dns-lookup-name <name> [nameserver]) --> <ip-address32>
; (dns-lookup-ip <ip-string | ip-address32> [nameserver]) --> <name>
; (dns-lookup-nameserver <name> [nameserver])
; --> <list of ip-strings of authoritative nameservers>
; --> <list of ip-address32s of authoritative nameservers>
; (dns-lookup-mail-exchanger <name> [nameserver])
; --> <list of names of mail-exchangers>
; --> <list of names of mail-exchangers>
;
; dns-lookup-name, dns-lookup-ip, dns-lookup-nameserver and
; dns-lookup-mail-exchanger are "simple lookup functions",
; they return the wanted information or #f.
; dns-lookup-ip can either be given an ip-string or an ip-address32.
;
; concurrent dns lookup:
; a concurrent lookup to all nameservers in /etc/resolv.conf is started,
; if the variable dns-concurrent-lookup is given as optional <nameserver>
; argument.
;
; (dns-lookup <name/ip-string> <type> [nameserver]) --> <dns-message>
;
; (dns-lookup <name | ip-string | ip-address32> <type> [nameserver])
; --> <dns-message>
; (show-dns-message <dns-message) --> the whole message, human readable
;
; a <dns-message> is a record, with several entries, which holds the whole
@ -49,18 +58,20 @@
; only useful in very special cases.
;
;
; (concurrent-lookup <simple lookup function> <name>)
; starts a concurrent lookup to all nameservers in /etc/resolv.conf.
; the simple lookup function defines the lookup type.
;
;
; some lookups return a hostname (e.g. mx).
; many applications need instead of a hostname a ip address.
; force-ip and force-ip-list guarantee that a ip address is
; returned.
;
; (force-ip <name>) --> <ip-string>
; (force-ip <name>) --> <ip>
; (force-ip-list <list of names>) --> <list of ips>
;
;
; useful converters:
;
; (address32->ip-string <ip-address32>) -> <ip-string>
; (ip-string->address32 <ip-string>) -> <ip-address32>
@ -151,6 +162,8 @@
(else (more))))
;; concurrent-flag
(define dns-concurrent-lookup 'dns-concurrent-lookup)
;;; -- globals and types
@ -254,9 +267,40 @@
(if *debug* (display "add-size-tag\n"))
(append (number->octet-pair (length m)) m))
;; converts an octeted-ip to a 32bit integer internet-address
(define (octet-ip->address32 ip)
(if *debug* (display "octet-ip->address32\n"))
(+ (arithmetic-shift (char->ascii (list-ref ip 0)) 24)
(arithmetic-shift (char->ascii (list-ref ip 1)) 16)
(arithmetic-shift (char->ascii (list-ref ip 2)) 8)
(char->ascii (list-ref ip 3))))
;; converts a 32 bit integer internet-address to an octeted-ip
(define (address32->octet-ip ip)
(if *debug* (display "number->octet-quad\n"))
(list (arithmetic-shift ip -24)
(modulo (arithmetic-shift ip -16) 256)
(modulo (arithmetic-shift ip -8) 256)
(modulo ip 256)))
;; converts an ip-string to an 32bit integer internet-address
(define (ip-string->address32 ip)
(if *debug* (display "ip-string->address32\n"))
(octet-ip->address32 (string->octet-ip ip)))
;; converts an ip-string to an 32bit integer internet-address
(define (address32->ip-string ip)
; (if *debug* (display "address32->ip-string\n"))
(format #f
"~a.~a.~a.~a"
(arithmetic-shift ip -24)
(modulo (arithmetic-shift ip -16) 256)
(modulo (arithmetic-shift ip -8) 256)
(modulo ip 256)))
;; converts an octeted-ip to an human readable ip-string
(define (ip->string s)
(if *debug* (display "ip->string\n"))
(define (octet-ip->string s)
(if *debug* (display "octet-ip->string\n"))
(format #f
"~a.~a.~a.~a"
(char->ascii (list-ref s 0))
@ -265,8 +309,8 @@
(char->ascii (list-ref s 3))))
;; converts an ip-string to octets
(define (string->ip s)
(if *debug* (display "string->ip\n"))
(define (string->octet-ip s)
(if *debug* (display "string->octet-ip\n"))
(let loop ((s s)
(result '()))
(cond
@ -285,7 +329,7 @@
314159265))))
;; checks if a string is a ip
(define (ip? s)
(define (ip-string? s)
(if *debug* (display "ip-string->in-addr\n"))
(let loop ((s s)
(count 0))
@ -304,6 +348,10 @@
(= count 3)
#t))))))
;; checks if v is a address32
(define (address32? v)
(and (number? v)
(<= 0 v #xffffffff)))
;; returns a in-addr.arpa name-string or #f (needed to resolve hostname by ip)
(define (ip-string->in-addr s)
@ -343,7 +391,7 @@
;; returns a IP if available (additonal type-a processing)
(define (force-ip name)
(let loop ((result (dns-lookup-name name)))
(if (ip? result)
(if (ip-string? result)
result
(loop (dns-lookup-name result)))))
@ -612,7 +660,7 @@
(if *debug* (display "parse-rr-data\n"))
(cond
((eq? type 'a)
(make-rr-data-a (ip->string data)))
(make-rr-data-a (octet-ip->address32 data)))
((eq? type 'ns)
(make-rr-data-ns (call-with-values
@ -932,7 +980,7 @@
ns))
((regexp-search (posix-string->regexp "nameserver[ ]+([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)") l)
=> (lambda (match)
(loop (append ns (list (match:substring match 1))))))
(loop (append ns (list (ip-string->address32 (match:substring match 1)))))))
(else
(loop ns))))))))
@ -960,12 +1008,12 @@
(for-each (lambda (nameserver)
(spawn
(lambda ()
(display "query sent to ")(display nameserver)(display " \n")
;(display "query sent to ")(display nameserver)(display " \n")
(let* ((result (apply lookup (list name nameserver))))
(enqueue! queue result)
(display "received reply from ")(display nameserver)(display ": ")(display result)(newline)
;(display "received reply from ")(display nameserver)(display ": ")(display result)(newline)
(release-lock lock)))))
(dns-find-nameserver-list))))
(map (lambda (adr32) (address32->ip-string adr32)) (dns-find-nameserver-list)))))
(let loop ((count (length nameserver-list)))
(obtain-lock lock)
@ -974,16 +1022,17 @@
result
(loop (- count 1)))))))
;; checks the arguments of the dns-lookup-* functions.
;; checks the arguments of the simple lookup functions.
;; if a nameserver-name is given and not a nameserver-ip
;; (dns-lookup-name nameserver) is called.
(define (check-args args)
(if (null? args)
(dns-find-nameserver)
(address32->ip-string (dns-find-nameserver) )
(let ((nameserver (car args)))
(if (ip? nameserver)
nameserver
(dns-lookup-name nameserver)))))
(cond
((ip-string? nameserver) nameserver)
((address32? nameserver) (address32->ip-string nameserver))
(else (address32->ip-string (dns-lookup-name nameserver)))))))
;; dns-lookup with more options than dns-lookup-*
@ -996,7 +1045,9 @@
(dns-error-messages condition more)
(exit #f))
(lambda ()
(let* ((ip-string (ip-string->in-addr name))
(let* ((ip-string (if (address32? name)
(ip-string->in-addr (address32->ip-string name))
(ip-string->in-addr name)))
(question (if ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
(make-octet-query-message (random 256) ip-string type 'in)
(make-octet-query-message (random 256) name type 'in)))
@ -1012,10 +1063,18 @@
dns-msg))))))
;; returns a lookup-function with concurrent-flag
(define (make-lookup-function simple-lookup-function)
(lambda (name . args)
(if (null? args)
(simple-lookup-function name)
(if (eq? (car args) dns-concurrent-lookup)
(concurrent-lookup simple-lookup-function name)
(simple-lookup-function name (car args))))))
;; looks up a hostname, returns an ip.
;; (dns-lookup-name <name> [nameserver])
(define (dns-lookup-name name . args)
(define (dns-simple-lookup-name name . args)
(call-with-current-continuation
(lambda (exit)
(with-handler
@ -1023,7 +1082,9 @@
(dns-error-messages condition more)
(exit #f))
(lambda ()
(let* ((ip-string (ip-string->in-addr name))
(let* ((ip-string (if (address32? name)
(ip-string->in-addr (address32->ip-string name))
(ip-string->in-addr name)))
(question (if ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
(signal 'not-a-hostname)
(make-octet-query-message (random 256) name 'a 'in)))
@ -1038,10 +1099,11 @@
(answers (filter-type (message:answers (dns-message:reply dns-msg)) 'a)))
(rr-data-a:ip (rr:data (car answers)))))))))
(define dns-lookup-name (make-lookup-function dns-simple-lookup-name))
;; looks up an ip, returns a hostname
;; (dns-inverse-lookup <name> [nameserver])
(define (dns-inverse-lookup ip . args)
(define (dns-simple-lookup-ip ip . args)
(call-with-current-continuation
(lambda (exit)
(with-handler
@ -1049,7 +1111,9 @@
(dns-error-messages condition more)
(exit #f))
(lambda ()
(let* ((ip-string (ip-string->in-addr ip))
(let* ((ip-string (if (address32? ip)
(ip-string->in-addr (address32->ip-string ip))
(ip-string->in-addr ip)))
(question (if ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
(make-octet-query-message (random 256) ip-string 'ptr 'in)
(signal 'not-a-ip)))
@ -1064,13 +1128,15 @@
(answers (filter-type (message:answers (dns-message:reply dns-msg)) 'ptr)))
(rr-data-ptr:name (rr:data (car answers)))))))))
(define dns-lookup-ip dns-inverse-lookup)
(define dns-lookup-ip (make-lookup-function dns-simple-lookup-ip))
(define dns-inverse-lookup dns-lookup-ip)
;; looks up an authoritative nameserver for a hostname
;; returns a list of nameservers
;; (dns-lookup-nameserver <name> [nameserver])
(define (dns-lookup-nameserver name . args)
(define (dns-simple-lookup-nameserver name . args)
(call-with-current-continuation
(lambda (exit)
(with-handler
@ -1078,7 +1144,9 @@
(dns-error-messages condition more)
(exit #f))
(lambda ()
(let* ((ip-string (ip-string->in-addr name))
(let* ((ip-string (if (address32? name)
(ip-string->in-addr (address32->ip-string name))
(ip-string->in-addr name)))
(question (if ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
(signal 'not-a-hostname)
(make-octet-query-message (random 256) name 'ns 'in)))
@ -1100,13 +1168,15 @@
(list (dns-lookup-name (rr-data-soa:mname (rr:data (car soa)))))
(map (lambda (elem) (rr-data-a:ip (rr:data elem))) add))))))))
(define dns-lookup-nameserver (make-lookup-function dns-simple-lookup-nameserver))
;; looks up a mail-exchanger for a hostname.
;; returns a list of mail-exchanger, sorted by their preference
;; if there are no mx-records in the answer-section,
;; implementation based on RFC2821
;; (dns-lookup-mail-exchanger <name> [nameserver])
(define (dns-lookup-mail-exchanger name . args)
(define (dns-simple-lookup-mail-exchanger name . args)
(call-with-current-continuation
(lambda (exit)
(with-handler
@ -1114,7 +1184,9 @@
(dns-error-messages condition more)
(exit #f))
(lambda ()
(let* ((ip-string (ip-string->in-addr name))
(let* ((ip-string (if (address32? name)
(ip-string->in-addr (address32->ip-string name))
(ip-string->in-addr name)))
(question (if ip-string ; if name is a ip-addr, the query is a in-addr.arpa address
(signal 'not-a-hostname)
(make-octet-query-message (random 256) name 'mx 'in)))
@ -1145,7 +1217,7 @@
(else
(map (lambda (elem) (rr-data-mx:exchanger (rr:data elem))) (sort-by-preference mx))))))))))
(define dns-lookup-mail-exchanger (make-lookup-function dns-simple-lookup-mail-exchanger))
;;; pretty-prints a dns-msg

View File

@ -182,19 +182,21 @@
net:daytime))
(define-interface dns-interface
(export dns-clear-cache
dns-lookup
dns-lookup-name
dns-inverse-lookup
dns-lookup-ip
dns-lookup-nameserver
dns-lookup-mail-exchanger
concurrent-lookup
show-dns-message
force-ip
force-ip-list
dns-find-nameserver
dns-find-nameserver-list))
(export dns-clear-cache ; clears the cache
dns-lookup ; complex lookup function
dns-lookup-name ; simple lookup function
dns-inverse-lookup ; obsolete, use dns-lookup-ip
dns-lookup-ip ; simple lookup function
dns-lookup-nameserver ; simple lookup function
dns-lookup-mail-exchanger ; simple lookpu function
dns-concurrent-lookup ; the concurrent lookup variable
show-dns-message ; prints a human readable dns-msg
force-ip ; reruns a lookup until a ip is resolved
force-ip-list ; reruns a lookup until a list of ips is resolved
address32->ip-string ; converts a address32 in an ip-string
ip-string->address32 ; converts a ip-string in an address32
dns-find-nameserver ; returns a nameserver
dns-find-nameserver-list)) ; returns a list of nameservers
(define-interface cgi-script-interface
(export cgi-form-query))