Function: socks-send-command

socks-send-command is a byte-compiled function defined in socks.el.gz.

Signature

(socks-send-command PROC COMMAND ATYPE ADDRESS PORT)

Documentation

Send COMMAND to SOCKS service PROC for proxying ADDRESS and PORT.

When ATYPE indicates an IP, param ADDRESS must be given as raw bytes.

Source Code

;; Defined in /usr/src/emacs/lisp/net/socks.el.gz
(defun socks-send-command (proc command atype address port)
  "Send COMMAND to SOCKS service PROC for proxying ADDRESS and PORT.
When ATYPE indicates an IP, param ADDRESS must be given as raw bytes."
  (let ((addr (cond
	       ((or (= atype socks-address-type-v4)
		    (= atype socks-address-type-v6))
		address)
	       ((= atype socks-address-type-name)
		(format "%c%s" (length address) address))
	       (t
		(error "Unknown address type: %d" atype))))
        trailing
	request version)
    (or (process-get proc 'socks)
        (error "socks-send-command called on non-SOCKS connection %S" proc))
    (process-put proc 'socks-state socks-state-waiting)
    (setq version (process-get proc 'socks-server-protocol))
    (cond
     ((equal version 'http)
      (setq request (format (concat
			     "CONNECT %s:%d HTTP/1.0\r\n"
			     "User-Agent: Emacs/SOCKS v1.0\r\n"
			     "\r\n")
			    (cond
			     ((equal atype socks-address-type-name) address)
			     (t
			      (error "Unsupported address type for HTTP: %d" atype)))
			    port)))
     ((and (eq version '4a)
           (setf addr "\0\0\0\1"
                 trailing (concat address "\0")
                 version 4 ; become version 4
                 (process-get proc 'socks-server-protocol) 4)
           nil)) ; fall through
     ((equal version 4)
      (setq request (concat
		     (unibyte-string
		      version             ; version
		      command             ; command
		      (ash port -8)       ; port, high byte
		      (logand port #xff)) ; port, low byte
		     addr                 ; address
                     socks-username       ; username
                     "\0"                 ; terminate username
                     trailing)))          ; optional host to look up
     ((equal version 5)
      (setq request (concat
		     (unibyte-string
		      version		; version
		      command		; command
		      0			; reserved
		      atype)		; address type
		     addr		; address
		     (unibyte-string
                      (ash port -8)          ; port, high byte
		      (logand port #xff))))) ; port, low byte
     (t
      (error "Unknown protocol version: %d" version)))
    (process-send-string proc request)
    (socks-wait-for-state-change proc socks-state-waiting)
    (process-status proc)
    (if (= (or (process-get proc 'socks-reply) 1) socks-response-success)
	nil				; Sweet sweet success!
      (delete-process proc)
      (error "SOCKS: %s"
             (let ((err (process-get proc 'socks-reply)))
               (if (eql version 5)
                   (nth (or err 1) socks-errors)
                 ;; The defined error codes for v4 range from
                 ;; 90-93, but we store them in a simple list.
                 (nth (pcase err (90 0) (92 2) (93 3) (_ 1))
                      socks--errors-4)))))
    proc))