协议概览
Xray-core 实现了一系列多样化的代理协议,每个协议都通过其 init() 函数中的 common.RegisterConfig() 进行注册。核心根据配置将入站连接分发给相应的协议处理器,出站处理器则连接到上游服务器或目标地址。
协议能力矩阵
| 协议 | 入站 | 出站 | TCP | UDP | 加密方式 | 多路复用支持 | 认证方式 |
|---|---|---|---|---|---|---|---|
| VMess | 是 | 是 | 是 | 是 | AES-128-GCM、ChaCha20-Poly1305、无 | 是 (v1.mux.cool) | UUID + AEAD 头部 |
| VLESS | 是 | 是 | 是 | 是 | 无(依赖传输层 TLS) | 是 (XUDP) | UUID |
| Trojan | 是 | 是 | 是 | 是 | 无(依赖 TLS) | 否 | SHA224(password) |
| Shadowsocks | 是 | 是 | 是 | 是 | AES-128-GCM、AES-256-GCM、ChaCha20-Poly1305、XChaCha20、无 | 否 | 按密钥 |
| Shadowsocks 2022 | 是 | 是 | 是 | 是 | 2022-blake3-aes-128-gcm、2022-blake3-aes-256-gcm 等 | 否 | PSK (base64) |
| SOCKS5 | 是 | 是 | 是 | 是 (UDP Associate) | 无 | 否 | 用户名/密码 |
| HTTP | 是 | 是 | 是 | 否 | 无(HTTPS 通过传输层) | 否 | Basic Auth |
| Dokodemo-door | 是 | 否 | 是 | 是 | 不适用(透明代理) | 否 | 不适用 |
| Freedom | 否 | 是 | 是 | 是 | 不适用(直连) | 否 | 不适用 |
| Blackhole | 否 | 是 | 不适用 | 不适用 | 不适用 | 否 | 不适用 |
| WireGuard | 是 | 是 | 是 | 是 | Noise 协议 (Curve25519、ChaCha20-Poly1305) | 否 | 公钥/私钥 |
| Hysteria2 | 是 | 是 | 是 | 是 (QUIC 数据报) | QUIC TLS 1.3 | 否 | 基于密码 |
架构
入站处理器接口
每个入站协议都实现了 proxy.Inbound 接口:
go
type Inbound interface {
Network() []net.Network // Supported networks (TCP, UDP, UNIX)
Process(ctx context.Context,
network net.Network,
conn stat.Connection,
dispatcher routing.Dispatcher) error
}关键源码:proxy/proxy.go
出站处理器接口
每个出站协议都实现了 proxy.Outbound 接口:
go
type Outbound interface {
Process(ctx context.Context,
link *transport.Link,
dialer internet.Dialer) error
}关键源码:proxy/proxy.go
注册模式
所有协议都在各自的 init() 函数中使用相同的模式进行自注册:
go
func init() {
common.Must(common.RegisterConfig((*Config)(nil),
func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*Config))
}))
}连接流程
mermaid
graph LR
A[客户端] -->|传输层| B[入站处理器]
B -->|解码协议| C[分发器]
C -->|路由规则| D[出站处理器]
D -->|编码协议| E[传输层]
E --> F[目标地址]Splice 拷贝级别
入站/出站元数据上的 CanSpliceCopy 字段控制零拷贝优化:
| 值 | 含义 |
|---|---|
| 0 | 不使用 splice |
| 1 | 允许 splice(direct/dokodemo) |
| 2 | 握手后可使用 splice(socks/http 原始模式) |
| 3 | 完全支持 splice(加密协议) |
地址解析
大多数协议使用 protocol.NewAddressParser,采用 SOCKS5 风格的地址族字节:
| 字节值 | 地址族 |
|---|---|
0x01 | IPv4(4 字节) |
0x03 | 域名(1 字节长度前缀 + 字符串) |
0x04 | IPv6(16 字节) |
VMess 使用不同的编排方式:0x01 = IPv4、0x02 = 域名、0x03 = IPv6,且采用端口在前、地址在后的格式。
源码:proxy/vmess/encoding/encoding.go:12-17、proxy/trojan/protocol.go:16-20、proxy/shadowsocks/protocol.go:24-31
关键源码文件
| 协议 | 目录 |
|---|---|
| VMess | proxy/vmess/(aead/、encoding/、inbound/、outbound/) |
| VLESS | proxy/vless/ |
| Trojan | proxy/trojan/ |
| Shadowsocks | proxy/shadowsocks/ |
| Shadowsocks 2022 | proxy/shadowsocks_2022/ |
| SOCKS | proxy/socks/ |
| HTTP | proxy/http/ |
| Dokodemo-door | proxy/dokodemo/ |
| Freedom | proxy/freedom/ |
| Blackhole | proxy/blackhole/ |
| WireGuard | proxy/wireguard/ |
| Hysteria2 | proxy/hysteria/ |