Metadata-Version: 2.4
Name: asyncio-socks-server
Version: 1.0.0
Summary: A SOCKS5 toolchain/framework with programmable addons
Project-URL: Homepage, https://github.com/Amaindex/asyncio-socks-server
Project-URL: Repository, https://github.com/Amaindex/asyncio-socks-server
Project-URL: Issues, https://github.com/Amaindex/asyncio-socks-server/issues
Author-email: Amaindex <amaindex@outlook.com>
License-Expression: MIT
License-File: LICENSE
Keywords: addon,asyncio,proxy,socks5
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: Proxy Servers
Requires-Python: >=3.12
Description-Content-Type: text/markdown

# asyncio-socks-server

[![Tests](https://github.com/Amaindex/asyncio-socks-server/actions/workflows/tests.yml/badge.svg)](https://github.com/Amaindex/asyncio-socks-server/actions/workflows/tests.yml)
[![Docker](https://github.com/Amaindex/asyncio-socks-server/actions/workflows/docker.yml/badge.svg)](https://github.com/Amaindex/asyncio-socks-server/actions/workflows/docker.yml)
[![Python](https://img.shields.io/badge/python-3.12%2B-blue)](pyproject.toml)
[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)

> SOCKS5 server with async Python addon hooks.

**[中文](README.zh-CN.md)**

## Overview

asyncio-socks-server is a SOCKS5 server built around async hooks. The core handles protocol parsing, relay, and hook dispatch. Addons handle authentication, routing, data transformation, logging, and stats.

Design:

- **Three hook models**: competitive, pipeline, observational
- **Chain proxying is an addon**: TCP uses `ChainRouter`; UDP uses UDP-over-TCP entry and exit components
- **No runtime dependencies**: Python stdlib only

## Architecture

```text
SOCKS5 Client          Server                          Target / Next Hop
─────────────          ──────                          ──────────────────

TCP CONNECT ─────────▶ handshake
                       ├─ dispatch_auth (competitive)
                       └─ dispatch_connect (competitive)
                          ├─ no addon ───────────────▶ direct
                          └─ ChainRouter ────────────▶ next SOCKS5 hop

                       relay: dispatch_data (pipeline) per chunk
                       teardown: dispatch_flow_close (observational)

UDP ASSOCIATE ───────▶ handshake
                       └─ dispatch_udp_associate (competitive)
                          ├─ no addon ──▶ UdpRelay
                          └─ UdpOverTcpEntry ──▶ TCP frames ──▶ exit node
```

Modules: **core** (protocol), **server** (handshake/relay/lifecycle), **client** (SOCKS5 client), **addons** (hooks and built-ins). See [docs/architecture.md](docs/architecture.md).

## Capabilities

- 8 async hooks for auth, connection routing, data handling, and lifecycle
- TCP chain proxying through `ChainRouter`
- UDP chaining through `UdpOverTcpEntry` and `UdpOverTcpExitServer`
- Per-flow identity and byte counters through `Flow`
- Optional local JSON stats API through `StatsServer`
- Shared-socket UDP relay with TTL route cleanup
- IPv6 dual-stack listener and Happy Eyeballs-style client fallback
- Python stdlib runtime

## API Status

The 1.x API is the package root: `Server`, `Addon`, `Address`, `Flow`,
`ChainRouter`, `StatsServer`, `connect`, and related types.

See [docs/public-api.md](docs/public-api.md).

## Quick Start

### CLI

```shell
asyncio_socks_server                              # basic proxy
asyncio_socks_server --auth user:pass --port 9050 # with auth
```

### Python API

```python
from asyncio_socks_server import Server

server = Server(host="::", port=1080)
server.run()
```

With addons:

```python
from asyncio_socks_server import ChainRouter, Server, StatsServer

server = Server(
    addons=[
        StatsServer(host="127.0.0.1", port=9900),
        ChainRouter("10.0.0.5:1080"),
    ],
)
server.run()
```

Addon order is list order. Hook API: [docs/addon-model.md](docs/addon-model.md).

### Chain Proxying

Each node only knows its next hop:

```python
# Node A → B → C → Target
Server(addons=[ChainRouter("B:1080")])  # A
Server(addons=[ChainRouter("C:1080")])  # B
Server()                                 # C: direct
```

UDP chaining:

```python
# Entry node
from asyncio_socks_server import UdpOverTcpEntry
server = Server(addons=[UdpOverTcpEntry("exit-host:9020")])

# Exit node (standalone TCP service)
from asyncio_socks_server import UdpOverTcpExitServer
exit_srv = UdpOverTcpExitServer(host="::", port=9020)
exit_srv.run()
```

### Client Library

```python
from asyncio_socks_server import connect, Address

conn = await connect(
    proxy_addr=Address("127.0.0.1", 1080),
    target_addr=Address("93.184.216.34", 443),
)
conn.writer.write(b"hello")
await conn.writer.drain()
data = await conn.reader.read(4096)
```

## Build

Python 3.12+. Development uses [uv](https://docs.astral.sh/uv/).

```shell
git clone https://github.com/Amaindex/asyncio-socks-server.git
cd asyncio-socks-server
uv sync
```

Development:

```shell
uv run ruff check .          # lint
uv run ruff format --check . # format check
uv run pytest tests/ -v      # test (260 cases)
uv run pyright src/           # type check
uv build                     # package build
```

## Public API

Stable imports live at the package root:

```python
from asyncio_socks_server import (
    Addon,
    Address,
    ChainRouter,
    Connection,
    Direction,
    FileAuth,
    Flow,
    IPFilter,
    Logger,
    Server,
    StatsServer,
    TrafficCounter,
    UdpOverTcpEntry,
    UdpOverTcpExitServer,
    UdpRelayBase,
    connect,
)
```

Submodules are importable. Root exports are the compatibility contract.

## Configuration

No config files.

CLI mode (basic proxy):

| Flag | Default | Description |
|------|---------|-------------|
| `--host` | `::` | Bind address |
| `--port` | `1080` | Bind port |
| `--auth` | None | `username:password` |
| `--log-level` | `INFO` | `DEBUG` / `INFO` / `WARNING` / `ERROR` |

For addons or custom behavior, instantiate `Server` from Python. See [docs/addon-model.md](docs/addon-model.md).

## Deployment

```shell
pip install asyncio-socks-server
```

Docker:

```shell
docker run --rm -p 1080:1080 amaindex/asyncio-socks-server
```

PyPI and Docker Hub artifacts are published from GitHub releases.

## Release and CI

GitHub Actions runs lint, format check, pyright, package build, and tests for pull requests and pushes to `main`. Tests run on Python 3.12 and 3.13.

Release workflow:

1. Create a GitHub Release from a tag such as `v1.0.0`.
2. The release workflow builds and publishes the Python package.
3. The Docker workflow builds and pushes the image when Docker Hub credentials are configured.

## Documentation

| Doc | Content |
|-----|---------|
| [Architecture](docs/architecture.md) | Component relationships, data flow diagrams, UDP relay design, Flow context, design decisions |
| [Addon Model](docs/addon-model.md) | Hook API reference, execution models, chain proxying, StatsServer, custom addon patterns |
| [Public API](docs/public-api.md) | 1.x compatibility surface, root exports, hook contracts, Stats API |

## License

MIT
