Tor's extensions to the SOCKS protocol

Overview

The SOCKS protocol provides a generic interface for TCP proxies. Client software connects to a SOCKS server via TCP, and requests a TCP connection to another address and port. The SOCKS server establishes the connection, and reports success or failure to the client. After the connection has been established, the client application uses the TCP stream as usual.

Except as noted below, Tor supports SOCKS4 as defined here, SOCKS4A as defined here, and SOCKS5 as defined in RFC 1928 and RFC 1929.

The stickiest issue for Tor in supporting clients, in practice, is forcing DNS lookups to occur at the OR side: if clients do their own DNS lookup, the DNS server can learn which addresses the client wants to reach. SOCKS4 supports addressing by IPv4 address; SOCKS4A is a kludge on top of SOCKS4 to allow addressing by hostname; SOCKS5 supports IPv4, IPv6, and hostnames.

Extent of support

Tor supports the SOCKS4, SOCKS4A, and SOCKS5 standards, except as follows:

SOCKS4, SOCKS4A:

  • The BIND command is not supported.

SOCKS5:

  • The SOCKS5 "UDP ASSOCIATE" command is not supported.
  • The SOCKS5 "BIND" command is not supported.
  • SOCKS5 GSSAPI authentication, and its subnegotiation protocol, are not supported, even though they are listed as "MUST support" by RFC 1928.
  • As an extension to support some broken clients, the C tor implementation allows clients to pass "USERNAME/PASSWORD" authentication message to us even if no authentication was selected. This technically violates RFC 1929, but ensures interoperability with somewhat broken SOCKS5 client implementations.

Name lookup

As an extension to SOCKS4A and SOCKS5, Tor implements a new command value, "RESOLVE" ([F0]). When Tor receives a RESOLVE SOCKS command, it initiates a remote lookup of the hostname provided as the target address in the SOCKS request. The reply is either an error (if the address couldn't be resolved) or a success response. In the case of success, the address is stored in the portion of the SOCKS response reserved for remote IP address.

(We support RESOLVE in SOCKS4 too, even though it is unnecessary.)

For SOCKS5 only, we support reverse resolution with a new command value, RESOLVE_PTR ([F1]). In response to a RESOLVE_PTR SOCKS5 command with an IPv4 address as its target, Tor attempts to find the canonical hostname for that IPv4 record, and returns it in the "server bound address" portion of the reply. (This command was not supported before Tor 0.1.2.2-alpha.)

HTTP-resistance

Tor checks the first byte of each SOCKS request to see whether it looks more like an HTTP request (that is, it starts with a "G", "H", or "P"). If so, Tor returns a small webpage, telling the user that their browser is misconfigured. This is helpful for the many users who mistakenly try to use Tor as an HTTP proxy instead of a SOCKS proxy.

Optimistic data

Tor allows SOCKS clients to send connection data before Tor has sent a SOCKS response. When using an exit node that supports "optimistic data", Tor will send such data to the server without waiting to see whether the connection attempt succeeds. This behavior can save a single round-trip time when starting connections with a protocol where the client speaks first (like HTTP). Clients that do this must be ready to hear that their connection has succeeded or failed after they have sent the data.

Extended error codes

We define a set of additional extension error codes that can be returned by our SOCKS implementation in response to failed onion service connections.

(In the C Tor implementation, these error codes can be disabled via the ExtendedErrors flag. In Arti, these error codes are enabled whenever onion services are.)

  • [F0] Onion Service Descriptor Can Not be Found

    The requested onion service descriptor can't be found on the hashring and thus not reachable by the client.

  • [F1] Onion Service Descriptor Is Invalid

    The requested onion service descriptor can't be parsed or signature validation failed.

  • [F2] Onion Service Introduction Failed

    Client failed to introduce to the service meaning the descriptor was found but the service is not anymore at the introduction points. The service has likely changed its descriptor or is not running.

  • [F3] Onion Service Rendezvous Failed

    Client failed to rendezvous with the service which means that the client is unable to finalize the connection.

  • [F4] Onion Service Missing Client Authorization

    Tor was able to download the requested onion service descriptor but is unable to decrypt its content because it is missing client authorization information for it.

  • [F5] Onion Service Wrong Client Authorization

    Tor was able to download the requested onion service descriptor but is unable to decrypt its content using the client authorization information it has. This means the client access were revoked.

  • [F6] Onion Service Invalid Address

    The given .onion address is invalid. In one of these cases this error is returned: address checksum doesn't match, ed25519 public key is invalid or the encoding is invalid.

  • [F7] Onion Service Introduction Timed Out

    Similar to [F2] code but in this case, all introduction attempts have failed due to a time out.

(Note that not all of the above error codes are currently returned by Arti as of August 2023.)

Stream isolation

As part of Tor's support for stream isolation, we allow the application to pass stream isolation parameters via the SOCKS authentication fields.

Specifically, two streams that have differing SOCKS authentication values are never allowed to share the same circuit.

Note that in C tor, stream isolation is not implemented for onion service streams; in Arti, however, it is.

Two streams are considered to have the same SOCKS authentication values if and only if one of the following is true:

  • They are both SOCKS4 or SOCKS4a, with the same user "ID" string.
  • They are both SOCKS5, with no authentication.
  • They are both SOCKS5 with USERNAME/PASSWORD authentication, and they have identical usernames and identical passwords.

For more information on stream isolation, see documentation in the C tor manual page.

In C tor, stream isolation based on socks authentication can be disabled with the NoIsolateSocksAuth option.

Inferring IP version preference

The Tor protocol's BEGIN messages include flags to indicate preferences for IPv4 versus IPv6.

When opening streams based on SOCKS requests, the "IPv6 okay" flag is set, and the other flags are left cleared, except as follows:

If the address is an IPv4 address (received via SOCKS4, SOCKS5 address type 1, or a hostname string containing a literal IPv4 address) then the "IPv6 okay" flag is cleared.

If the address is an IPv6 address (via SOCKS5 address type 4, or a hostname string containing a literal IPv6 address) then the "IPv4 not okay" flag is set.

User-specified configuration options may override this behavior.