Skip to content

Commit

Permalink
modify buffer size and complete readme
Browse files Browse the repository at this point in the history
  • Loading branch information
handhand committed Jan 17, 2022
1 parent 2b8d638 commit f259a58
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <string>
#include "lightsocks_android_encryptor.h"
#include "lightsocks_android_encryptor.h"
#define BUFFER_SIZE = 65536
using namespace std;

/**
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/cpp/lightsocks/lightsocks_android_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ void proxy_listener_cb(evconnlistener *ev, int sock, sockaddr *client_addr,
*/
bufferevent_filter_result dest_filter_in(evbuffer *src, evbuffer *dst, ssize_t dst_limit,
bufferevent_flush_mode mode, void *ctx) {
char buffer[10]{0};
char buffer[BUFFER_SIZE]{0};
int len = 0;
while (true)
{
Expand All @@ -166,7 +166,7 @@ bufferevent_filter_result dest_filter_in(evbuffer *src, evbuffer *dst, ssize_t d
bufferevent_filter_result dest_filter_out(evbuffer *src, evbuffer *dst, ev_ssize_t dst_limit,
bufferevent_flush_mode mode, void *ctx)
{
char buffer[1024]{0};
char buffer[BUFFER_SIZE]{0};
int len = 0;
while (true)
{
Expand Down
25 changes: 0 additions & 25 deletions app/src/main/cpp/nativelib/lightsocks_droid.cpp

This file was deleted.

36 changes: 24 additions & 12 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ TAP等同于一个以太网设备,它操作第二层数据包如以太网数

操作系统通过TUN/TAP设备向绑定该设备的用户空间的程序发送数据,反之,用户空间的程序也可以像操作硬件网络设备那样,通过TUN/TAP设备发送数据。

Android的VpnService,就是系统将所有的流量都转发到这个/dev/tun中,并把/dev/tun的fd返回给我们,我们可以通过读取这个fd,读到所有的原始ip包。

### ToyVPN解析:

以下是对Android官方例子ToyVpn的一些解读:

拓扑参考:
https://github.com/daBisNewBee/Notes/blob/master/ToyVpn.md

Expand All @@ -36,9 +40,11 @@ Android的VpnService中可以获取到系统转发过来的IP协议的数据包

### tun2socks

Tun2socks是badvpn的一部分,作用是读取系统中发送到虚拟网卡tun的数据包(注意tun设备工作在IP层的,tun2socks读取到的是IP协议的数据包),然后通过协议栈的解析,转换为第5层的socks5协议
由于我们从/dev/tun中读取到的是原始的ip包,要进行处理需要大量工作,幸好有一个库已经为我们做好了这方面的工作,事实上所有的科学上网Android客户端都可以见到他的身影

tun2socks 官方例子解析:
Tun2socks是badvpn的一部分,可以把所有读取到的ip数据包,通过协议栈的解析,转换为第5层的socks5协议。

#### tun2socks官方例子解析:(运行在linux上)

需要手动新建一个tun设备,并为这个接口设置10.0.0.1的IP;

Expand All @@ -62,25 +68,27 @@ https://www.brobwind.com/archives/824

### 关于转发udp和dns:

在PC的浏览器上设置socks代理,浏览器会把域名也放到socks数据包中,由服务器做解析并返回数据,所以只需要用到tcp的协议。但是对于VpnService这种透明代理来说,域名的解析需要由客户端发起,所以代理需要同时支持udp协议(特别是科学上网的情况下)
在PC的浏览器上设置socks代理(如使用lightsocks-client),浏览器会把域名也放到socks数据包中,由服务器做解析并返回数据,所以只需要用到tcp的协议。

socks5协议是支持udp的,简单的过程是客户端连接socks5服务后,发送udp associate命令,服务端另外打开一个udp端口并告诉客户端,客户端然后就将udp数据包发向该端口,由服务端转发
但是对于VpnService这种透明代理来说,域名的解析需要由客户端发起,所以代理需要同时支持udp协议(特别是科学上网的情况下,防止DNS poisoning)。从这个角度来看的话,单单靠lisghtsocks应该是无法支持mobile端的科学上网的

流程见https://stackoverflow.com/a/47079318/4376839
事实上,我们从/dev/tun中读取到除了一般tcp连接的ip包,还包括了如dns请求的udp协议的ip包。所以我们需要解决的问题是,如何转发这些udp包进行dns查询?

注意这是一个UDP over UDP的隧道 https://stackoverflow.com/questions/41967217/why-does-socks5-require-to-relay-udp-over-udp
socks5协议是支持udp的,简单的过程是客户端连接socks5服务后,发送udp associate命令,服务端另外打开一个udp端口并告诉客户端,客户端然后就将udp数据包发向该端口,由服务端转发。

这是一个UDP over UDP的隧道 https://stackoverflow.com/questions/41967217/why-does-socks5-require-to-relay-udp-over-udp (流程见https://stackoverflow.com/a/47079318/4376839)

Tun2socks没有用这种方式,而是自己实现了一个UDP over TCP的隧道,由于这不是协议标准,所以需要在服务端额外打开一个程序,用来解析数据。
Tun2socks没有用这种方式,而是自己实现了一个UDP over TCP的隧道,由于这不是协议标准,所以需要在服务端额外打开一个程序(udpgw),用来解析数据。

#### udpgw

https://github.com/ambrop72/badvpn/issues/15
tun2socks的流程是,当客户端有udp包需要发送时,首先通过一般的socks5协议,经过socks5代理服务器和badvpn-udpgw建立tcp连接,然后再在该连接上发送需要转发的udp包(这时是整个udp包作为数据),由badvpn-udpgw解析并发送实际的udp包。

The udpgw mechanism works such that tun2socks establishes a TCP connection to udpgw, through the SOCKS server. Udpgw sends and receives UDP packets using normal OS network access.
使用这种方法对我们开发lightsocks android客户端还有个好处,即所有数据都是通过socks5发送,可以统一进行加密,无需另外对udp处理。不好的地方在于需要在服务端做额外的处理。

在服务端运行:badvpn-udpgw --listen-addr 127.0.0.1:7300
referenc: https://github.com/ambrop72/badvpn/issues/15 (The udpgw mechanism works such that tun2socks establishes a TCP connection to udpgw, through the SOCKS server. Udpgw sends and receives UDP packets using normal OS network access.)

整个流程是,当客户端有udp包需要发送时,首先通过一般的socks5协议,经过socks5代理服务器和badvpn-udpgw建立tcp连接,然后再在该连接上发送需要转发的udp包(这时整个udp包作为数据),由badvpn-udpgw解析并发送实际的udp包。
在服务端运行的命令是:badvpn-udpgw --listen-addr 127.0.0.1:7300

在tun2socks.c中device_read_handler_send是一个callback,当读取到tun设备时会被回调,同时获得从tun中读取的数据包,然后会调用process_device_udp_packet ,处理udp的数据包;最终会调用到udpgw_client/UdpGwGlient.c中的connection_send(),在connect_send()中可以看到将flag标记(如该包是否是dns包,如果是dns包,udpgw应该是直接用服务端设置的dns服务器,而忽略原包的目标地址),数据包原地址和目标地址,以及整个原udp包(包括header)一起作为payload写入缓存中进行发送。

Expand All @@ -102,7 +110,11 @@ badvpn里已经包含了编译udpgw的脚本,在badvpn上一级目录执行以

docker exec -t lightsocks cat /root/.lightsocks.json

### ndk编译libevent
### lightsocks-androidx结构

VpnService -> /dev/tun -> tun2socks发送到App本地端口 -> 使用libevent读取socks协议数据并加密 -> 发送到lightsocks-server

#### ndk编译libevent

直接用libevent的CMakeLists.txt,在gradle传入正确的cmake参数即可
"-DANDROID=TRUE",
Expand Down

0 comments on commit f259a58

Please sign in to comment.