Skip to content

Commit

Permalink
Merge pull request #17 from apernet/wip-sockopts
Browse files Browse the repository at this point in the history
Add docs for quic.sockopts in client config
  • Loading branch information
tobyxdd authored Apr 13, 2024
2 parents 6373328 + 840dd64 commit 721668e
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 0 deletions.
26 changes: 26 additions & 0 deletions docs/docs/advanced/FD-Control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# FD Control Protocol

> This feature is mainly used for developing Android proxy apps.
The Hysteria client supports sending the file descriptor (fd) of outbound QUIC connections to any process listening on `fdControlUnixSocket`.

**Note:** `fdControlUnixSocket` is currently only effective for outbound QUIC connections. Third-party Android clients using this feature will need to handle additional DNS resolution requests for the Hysteria server domain, or make sure that the `server` option in the Hysteria client config is an IP address, not a domain.

## Roles

- Server: The third-party process listening on `fdControlUnixSocket`, e.g., the main process of an Android app.
- Client: The Hysteria client process.

## Server Implementation

1. Listen to a path-based Unix Socket, which must be of type `SOCK_STREAM`.
2. Use `accept(2)` to accept connections initiated by the client.
3. Receive a single `fd` sent by the client via `recvmsg(2)`.
4. Process the `fd` received in step 3 (e.g., by calling `VpnService.protect()`) and then close the `fd`.
5. Respond to the client with a single byte, notifying the client to continue operations. It is advised to respond with `'\x01'` under normal conditions; other values are currently undefined.
6. Close the connection established in step 2 - each connection only processes one `fd`.

## References

- [Server implementation by Nekobox](https://github.com/MatsuriDayo/libneko/blob/5277a5bfc889ee7a89462695b0e678c1bd4909b1/protect_server/protect_server_linux.go) (Go)
- [Server used for unit testing in Hysteria](https://github.com/apernet/hysteria/blob/6b5486fc09d22c3fb4a1cc78c799c8cfe81e6dce/app/internal/sockopts/fd_control_unix_socket_test.py) (Python)
26 changes: 26 additions & 0 deletions docs/docs/advanced/FD-Control.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# FD Control 协议

> 此特性主要用于 Android 代理客户端开发。
Hysteria 客户端使用此协议将出站 QUIC 连接的文件描述符(File Descriptor,下称 `fd`)发送给监听 `fdControlUnixSocket` 的进程。

**注意:** `fdControlUnixSocket` 目前仅对出站 QUIC 连接生效。使用此特性实现第三方 Android 客户端需要对 Hysteria 服务端域名的 DNS 解析请求进行额外的处理,或者确保在 Hysteria 客户端配置的 `server` 选项中填入 IP 地址。

## 角色

- 服务端: 监听 `fdControlUnixSocket` 的第三方进程,例如 Android 客户端主进程。
- 客户端: Hysteria 客户端进程。

## 服务端实现步骤

1. 监听一个基于路径的 Unix Socket, 类型必须为 `SOCK_STREAM`
2. 使用 `accept(2)` 接受由客户端发起的连接。
3. 通过 `recvmsg(2)` 接收由客户端发送的单个 `fd`
4. 对第 3 步接收到的 `fd` 进行处理(例如调用 `VpnService.protect()`),并关闭该 `fd`
5. 向客户端回应单个字节,通知客户端继续操作。建议在一切正常的情况下回应 `'\x01'`,其它响应值的行为暂未定义。
6. 关闭由第 2 步建立的连接,每个连接仅处理一个 `fd`

## 参考样例

- [Nekobox 的服务端实现](https://github.com/MatsuriDayo/libneko/blob/5277a5bfc889ee7a89462695b0e678c1bd4909b1/protect_server/protect_server_linux.go) (Go)
- [Hysteria 中用于单元测试的服务端](https://github.com/apernet/hysteria/blob/6b5486fc09d22c3fb4a1cc78c799c8cfe81e6dce/app/internal/sockopts/fd_control_unix_socket_test.py) (Python)
9 changes: 9 additions & 0 deletions docs/docs/advanced/Full-Client-Config.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ quic:
maxIdleTimeout: 30s # (5)!
keepAlivePeriod: 10s # (6)!
disablePathMTUDiscovery: false # (7)!
sockopts:
bindInterface: eth0 # (8)!
fwmark: 1234 # (9)!
fdControlUnixSocket: ./test.sock # (10)!
```

1. The initial QUIC stream receive window size.
Expand All @@ -106,9 +110,14 @@ quic:
5. The maximum idle timeout. How long until the client will consider the connection dead if no packets from the server are received.
6. The keep-alive period. How often the client will send a packet to the server to keep the connection alive.
7. Disable QUIC path MTU discovery.
8. (Linux only) Interface name. Forces QUIC packets to be sent through this interface.
9. (Linux only) The `SO_MARK` tag to be added to QUIC packets.
10. (Linux only) Path to a Unix Socket that is listened to by other processes. The Hysteria client will send the file descriptor (FD) used for the QUIC connection as ancillary information to this Unix Socket, allowing the listening process to perform other custom configurations. This option can be used in Android client development; please refer to the [FD Control Protocol](./FD-Control.md) for more details.

The default stream and connection receive window sizes are 8MB and 20MB, respectively. **We do not recommend changing these values unless you fully understand what you are doing.** If you choose to change these values, we recommend keeping the ratio of stream receive window to connection receive window at 2:5.

**Note:** The options under `sockopts` only applies to outbound QUIC connections, not to other possible outbound connections (e.g. DNS queries to resolve the server address).

## Bandwidth

```yaml
Expand Down
9 changes: 9 additions & 0 deletions docs/docs/advanced/Full-Client-Config.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ quic:
maxIdleTimeout: 30s # (5)!
keepAlivePeriod: 10s # (6)!
disablePathMTUDiscovery: false # (7)!
sockopts:
bindInterface: eth0 # (8)!
fwmark: 1234 # (9)!
fdControlUnixSocket: ./test.sock # (10)!
```

1. 初始的 QUIC 流接收窗口大小。
Expand All @@ -106,9 +110,14 @@ quic:
5. 最长空闲超时时间。客户端会在多长时间没有收到任何服务端数据后关闭连接。
6. 心跳包发送间隔。客户端会多久发送一次心跳包以保持连接。
7. 禁用 MTU 探测。
8. (仅限 Linux)接口名称。强制 QUIC 数据包通过此接口发送。
9. (仅限 Linux)要为 QUIC 数据包添加的 `SO_MARK` 标记。
10. (仅限 Linux)由其它进程监听的 Unix Socket 路径。<br>Hysteria 客户端会把 QUIC 连接所使用的文件描述符(File Descriptor)作为辅助信息(Ancillary Message)发送给该 Unix Socket,以便监听进程进行其它自定义的配置。<br>此选项可被用于 Android 客户端开发,请参考 [FD Control 协议](./FD-Control.md) 以了解更多细节。

默认的流和连接接收窗口大小分别为 8MB 和 20MB。**除非你完全明白自己在做什么,否则不建议修改这些值。**如果要改,建议保持流接收窗口与连接接收窗口的比例为 2:5。

**注意:** `sockopts` 项下的子选项目前仅对出站 QUIC 连接有效,对其它出站连接(例如为解析服务端地址而发送的 DNS 查询)无效。

## 带宽

```yaml
Expand Down
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ plugins:
- 完整客户端配置: docs/advanced/Full-Client-Config.md
- ACL: docs/advanced/ACL.md
- 流量统计 API: docs/advanced/Traffic-Stats-API.md
- FD Control 协议: docs/advanced/FD-Control.md
- 透明代理: docs/advanced/TPROXY.md
- 端口跳跃: docs/advanced/Port-Hopping.md
- 环境变量: docs/advanced/Environment-Variables.md
Expand Down Expand Up @@ -130,6 +131,7 @@ nav:
- Full Client Config: docs/advanced/Full-Client-Config.md
- ACL: docs/advanced/ACL.md
- Traffic Stats API: docs/advanced/Traffic-Stats-API.md
- FD Control Protocol: docs/advanced/FD-Control.md
- TProxy: docs/advanced/TPROXY.md
- Port Hopping: docs/advanced/Port-Hopping.md
- Environment Variables: docs/advanced/Environment-Variables.md
Expand Down

0 comments on commit 721668e

Please sign in to comment.