IPs are now 32bit integer internet addresses,
changed the API for concurrent-lookup, revised the documentation
This commit is contained in:
		
							parent
							
								
									27ff0f4326
								
							
						
					
					
						commit
						470c2fbab3
					
				|  | @ -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 | ||||
|  |  | |||
|  | @ -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)) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 cresh
						cresh