badvpn之tun2socks的socks5-udp模式
badvpn的tun2socks加上了选 项--socks5-udp,以支持直接将tun设备的udp数据包通过sock5代理直接发送。以前是封装为tcp数据包,然后发送给--udpgw-remote-server-addr指定的地址。然后udpgw程序再使用udp发向源服务器,并将接收的包转发回tun设备。
SocksUdpClient
在main函数中就根据命令行的模式不同,然后调用SocksUdpClient_Init对全局的socks_udp_client进行初使化。
socks_udp_client 使用平衡树来管理与sock5服务器的连接。
udp数据处理流程
在tun2socks.c的process_device_udp_packet
函数中对接收到的设备发送的udp数据进行处理转发。
根据udp的模式调用udpgw或udp通道:
// submit packet to udpgw or SOCKS UDP
if (udp_mode == UdpModeUdpgw) {
SocksUdpGwClient_SubmitPacket(&udpgw_client, local_addr, remote_addr,
is_dns, data, data_len);
} else if (udp_mode == UdpModeSocks) {
SocksUdpClient_SubmitPacket(&socks_udp_client, local_addr, remote_addr, data, data_len);
}
在SocksUdpClient_SubmitPacket
中在socks_udp_client 树里根据地址查找连接find_connection(o, local_addr)
,如果没有查找到就调用 connection_init
,查找到了就调用connection_send
发送数据。
connection_init流程
- 分配SocksUdpClient_connection对象con,并初使化
- 拷贝第一块数据,并设置first_job_handler为第一执行函数。
- BDatagram_Init初使化一个udp socket: con->socket
- 调用BSocksClient_Init分配和初使化socks5连接(con->socks),并设置状态回调:socks_state_handler
- 添加不活跃监视回调:send_monitor_handler
- 添加接收数据回调:recv_if_handler_send
然后在BReactor_Exec执行循环中执行了在connection_init里设置的BPendingGroup_ExecuteJob和first job。即first_job_handler,在first_job_handler里调用connection_send
函数。
connection_send流程
connection_send 组成一个udp socks5数据包。使用BufferWriter_EndPacket写入发送队列。
socks状态回调 socks_state_handler
第一个connection_send调用后,会触发socks_state_handler,在这里进行地址的转换,以及连接错误后释放资源。
弃了。
本来这个博文是因为下面这个报错,才研究代码时顺手记录的:
截止至最新版本的 4b7070d 代码中,如果使用--socks5-udp模式,windows下的程序会报错:
ERROR(SocksUdpClient): Low-level datagram error 10.95.27.60:55913, removing connection.
但测试中又发现,是由于使用的sscap的sock5不支持udp模式导致socks5服务器连不上导致的问题,不是badvpn代码的问题,所以先随便记录到这里。。。后续流程有缘再续