Socks proxy

Describe SOCKS 4/4a/5 proxy [L1 ].

MJ - When used in conjunction with Tor [L2 ] SOCKS4 can be used to anonymize all network traffic from Tcl. However, one of the major drawbacks of using SOCKS4 when trying to anonymize you browsing behaviour is that you need to provide an IP address. This means the hostname has to be resolved to an IP somehow. (usually by DNS) As a result, the administrator of the DNS server can get an idea of your online behaviour by the DNS lookups that are done. This issue is resolved by SOCKS4a [L3 ] which is an extension to SOCKS4. SOCKS4a allows hostnames in the connect request.

When connecting through a SOCKS4(a) proxy one request-response pair has to be handled before using the socket as a normal socket. The following proc will handle the request response pair for SOCKS4 and SOCKS4a proxies and returns a socket if successful. This socket can then be used as a normal Tcl socket. This was tested by opening an jabber connection with a (hacked) TkChat through TOR.

 # connect to host or ip on port through the SOCKS4(a) proxy. authenticate with username (default empty)
 # returns a socket that can be used to send and receive traffic from the remote host

 proc socks4connect {proxy_host proxy_port host port {username {}}} {
        set connect_request \x04\x01        
        append connect_request [binary format S $port]
        if {[regexp {[0-9]+.[0-9]+.[0-9]+.[0-9]+} $host]} {
                set use_host false
                append connect_request [binary format c4 [split $host .]]
        } else {
                # ip address 0.0.0.x is always invalid and signals that a hostname is specified
                set use_host true
                append connect_request [binary format c4 [split .]]        
        append connect_request $username
        append connect_request \x00
        if {$use_host} {
                append connect_request $host
                append connect_request \x00

        set s [socket $proxy_host $proxy_port]
        fconfigure $s -translation binary -buffering none
        puts -nonewline $s $connect_request

        set response [read $s 8]
        if {[string index $response 1] ne "\x5a"} {
                error "connection request rejected by proxy"
        } else {
                return $s

 set s [socks4connect phost pport ip/host port]
 # s can now be used as a normal socket

A simple SOCKS 5 client library for Tcl can be found at .

Category Networking