Function: dns--lookup

dns--lookup is a byte-compiled function defined in dns.el.gz.

Signature

(dns--lookup NAME CALLBACK TYPE FULL)

Source Code

;; Defined in /usr/src/emacs/lisp/net/dns.el.gz
(defun dns--lookup (name callback type full)
  (with-current-buffer (generate-new-buffer " *dns*")
    (set-buffer-multibyte nil)
    (let* ((tcp nil)
           (process
            (condition-case ()
                (let ((server (car dns-servers))
                      (coding-system-for-read 'binary)
                      (coding-system-for-write 'binary))
                  (if (featurep 'make-network-process '(:type datagram))
                      (make-network-process
                       :name "dns"
                       :coding 'binary
                       :buffer (current-buffer)
                       :host server
                       :service "domain"
                       :type 'datagram)
                    ;; On MS-Windows datagram sockets are not
                    ;; supported, so we fall back on opening a TCP
                    ;; connection to the DNS server.
                    (progn
                      (setq tcp t)
                      (open-network-stream "dns" (current-buffer)
                                           server "domain"))))
              (error
               (message
                "dns: Got an error while trying to talk to %s"
                (car dns-servers))
               nil)))
           (triggered nil)
           (buffer (current-buffer))
           timer)
      (if (not process)
          (progn
            (kill-buffer buffer)
            (funcall callback nil))
        ;; Call the callback if we don't get any response at all.
        (setq timer (run-at-time dns-timeout nil
                                 (lambda ()
                                   (unless triggered
                                     (setq triggered t)
                                     (delete-process process)
                                     (kill-buffer buffer)
                                     (funcall callback nil)))))
        (process-send-string
         process
         (dns-write `((id ,(random 65000))
                      (opcode query)
                      (queries ((,name (type ,type))))
                      (recursion-desired-p t))
                    tcp))
        (set-process-filter
         process
         (lambda (process string)
           (with-current-buffer (process-buffer process)
             (goto-char (point-max))
             (insert string)
             (goto-char (point-min))
             ;; If this is DNS, then we always get the full data in
             ;; one packet.  If it's TCP, we may only get part of the
             ;; data, but the first two bytes says how long the data
             ;; is supposed to be.
             (when (or (not tcp)
                       (>= (buffer-size) (dns-read-bytes 2)))
               (setq triggered t)
               (cancel-timer timer)
               (dns--filter process callback type full tcp)))))
        ;; In case we the process is deleted for some reason, then do
        ;; a failure callback.
        (set-process-sentinel
         process
         (lambda (_ state)
           (when (and (eq state 'deleted)
                      ;; Ensure we don't trigger this callback twice.
                      (not triggered))
             (setq triggered t)
             (cancel-timer timer)
             (kill-buffer buffer)
             (funcall callback nil))))))))