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))