# SOCKS Proxy

The `aiorpcx` package includes a SOCKS proxy client. It understands the `SOCKS4`, `SOCKS4a` and `SOCKS5` protocols.

## Exceptions

exception aiorpcx.SOCKSError

  The base class of SOCKS exceptions. Each raised exception will be an instance of a derived class.

exception aiorpcx.SOCKSProtocolError

  A subclass of `SOCKSError`. Raised when the proxy does not follow the `SOCKS` protocol.

exception aiorpcx.SOCKSFailure

  A subclass of `SOCKSError`. Raised when the proxy refuses or fails to make a connection.

## Authentication

Currently the only supported authentication method is with a username and password. Usernames can be used by all SOCKS protocols, but only `SOCKS5` uses the password.

class aiorpcx.SOCKSUserAuth

  A `namedtuple` for authentication with a SOCKS server. It has two members:

  username

    A string.

  password

    A string. Ignored by the `SOCKS4` and `SOCKS4a` protocols.

## Protocols

When creating a `SocksProxy` object, a protocol must be specified and be one of the following.

class aiorpcx.SOCKS4

  An abstract class representing the `SOCKS4` protocol.

class aiorpcx.SOCKS4a

  An abstract class representing the `SOCKS4a` protocol.

class aiorpcx.SOCKS5

  An abstract class representing the `SOCKS5` protocol.

## Proxy

You can create a `SOCKSProxy` object directly, but using one of its auto-detection class methods is likely more useful.

class aiorpcx.SOCKSProxy(address, protocol, auth)

  An object representing a SOCKS proxy. The address is a Python socket address typically a (host, port) pair for IPv4, and a (host, port, flowinfo, scopeid) tuple for IPv6.

  The protocol is one of `SOCKS4`, `SOCKS4a` and `SOCKS5`.

  auth is a `SOCKSUserAuth` object or `None`.

  After construction, `host`, `port` and `peername` are set to `None`.

  classmethod auto_detect_address(address, auth, \*, loop=None, timeout=5.0)

    Try to detect a SOCKS proxy at address.

    Protocols `SOCKS5`, `SOCKS4a` and `SOCKS4` are tried in order. If a SOCKS proxy is detected return a `SOCKSProxy` object, otherwise `None`. Returning a proxy object only means one was detected, not that it is functioning - for example, it may not have full network connectivity.

    auth is a `SOCKSUserAuth` object or `None`.

    If testing any protocol takes more than timeout seconds, it is timed out and taken as not detected.

    This class method is a coroutine.

  classmethod auto_detect_host(host, ports, auth, \*, loop=None, timeout=5.0)

    Try to detect a SOCKS proxy on host on one of the ports.

    Call `auto_detect_address()` for each `(host, port)` pair until a proxy is detected, and return it, otherwise `None`.

    auth is a `SOCKSUserAuth` object or `None`.

    If testing any protocol on any port takes more than timeout seconds, it is timed out and taken as not detected.

    This class method is a coroutine.

  create_connection(protocol_factory, host, port, \*, resolve=False, loop=None, ssl=None, family=0, proto=0, flags=0, timeout=30.0)

    Connect to (host, port) through the proxy in the background. When successful, the coroutine returns a `(transport, protocol, address)` triple, and sets the proxy attribute `peername`.

    - If resolve is `True`, host is resolved locally rather than by the proxy. family, proto, flags are the optional address family, protocol and flags passed to loop.getaddrinfo() to get a list of remote addresses. If given, these should all be integers from the corresponding `socket` module constants.

    - ssl is as documented for loop.create_connection().

    If successfully connected the `_address` member of the protocol is set. If resolve is `True` it is set to the successful address, otherwise `(host, port)`.

    If connecting takes more than timeout seconds an `asyncio.TimeoutError` exception is raised.

    This method is a coroutine.

  host

    Set on a successful `create_connection()` to the host passed to the proxy server. This will be the resolved address if its resolve argument was `True`.

  port

    Set on a successful `create_connection()` to the host passed to the proxy server.

  peername

    Set on a successful `create_connection()` to the result of `socket.getpeername()` on the socket connected to the proxy.