SOCKS5 (RFC 1928) 是最流行的代理协议之一。相比于透明代理,它多了一个协商和认证的过程。
1. 协议状态机
我们需要维护每个连接的状态:
enum socks_state {
STATE_HANDSHAKE, // 等待客户端发送版本号
STATE_AUTH, // 等待认证 (如用户名密码)
STATE_REQUEST, // 等待 CONNECT 请求
STATE_STREAM, // 数据转发阶段
STATE_CLOSED
};2. 核心逻辑
2.1. 握手阶段
客户端发送 0x05 (Version) +
NMETHODS + METHODS。 服务端回复
0x05 + METHOD (0x00 无需认证, 0x02
用户名密码)。
2.2. 请求阶段
客户端发送 VER + CMD (CONNECT)
+ RSV + ATYP +
DST.ADDR + DST.PORT。
服务端解析目标地址,调用
bufferevent_socket_connect 连接目标。
2.3. 转发阶段
连接成功后,回复客户端 0x00
(Success),然后进入
STATE_STREAM,逻辑同透明代理。
3. 代码骨架
void read_cb(struct bufferevent *bev, void *arg) {
struct client_ctx *ctx = arg;
switch (ctx->state) {
case STATE_HANDSHAKE:
handle_handshake(ctx);
break;
case STATE_REQUEST:
handle_request(ctx);
break;
case STATE_STREAM:
handle_stream(ctx);
break;
}
}4. 总结
SOCKS5 是练习协议解析和状态机管理的绝佳案例。通过这个项目,你将掌握如何用 Libevent 处理非流式(基于消息)的交互逻辑。
完整代码: 10-socks5.c
上一篇: 08-projects/transparent-proxy.md - 实战:透明代理 下一篇: 08-projects/redis-lite.md - 实战:简易 Redis