Pages

Monday, 30 July 2018

kcp的最佳伴侣-rsock

The best companion of kcptun.

Introduction

中文请点击这里.
rsock is neither accelerator, nor vpn. It merely turns a udp connection into multiple fake tcp connections, or multiple normal udp connections or both. It's very similar with udp because it's not reliable and has no flow control, timeout retransmission algorithms, etc. It's cross platform. It's supposed to used together with kcptun or other udp client with ARQ. The purpose of rsock is that prevent qos to udp from ISP if any. It supports Windows, Mac and Linux. To see introduction and usage of kcptun click here . And shadowsocks, click here .
REPEAT: Data transfer of rsock is NOT reliable. Reliable data tranfer should be taked care of by app level(kcptun).
The following picture brifely shows principles

Installation

There are precompiled binaries for 64bit Linux, 64bit Mac and x86/x64 windows. They can be downloaded from here.
For Windows users, you have to install winpcap first. winpcap
For other platforms, you can download source code and compile it by yourself. Compilation guide is here

Quick start

Server

Remember to add firewall rule if firewall enabled.
Take Linux as an exmaple:
# port=10000
# while [ $port -le 10010 ]
do
sudo ufw allow $port
port=$[ $port + 1]
done
It means allow client connects to server from port 10000 to 10010. (rsock use port range 10001-10010 by default. If you want to change the default value, please check Parameter Explanation section.)
sudo ./server_rsock_Linux -t 127.0.0.1:9999
Parameter explanation:
127.0.0.1:9999, target address,aka address of kcptun server working on.

Client

Take mac as an example:
sudo ./client_rsock_Darwin --taddr=x.x.x.x -l 127.0.0.1:30000
Parameter explanation:
-t x.x.x.x , Address of rsock server。Attention. This is different from server. It only contains ip.
-l , local listened udp address, aka target address of kcptun client(the address specified by -t).

NOTE

  1. If rsock doesn't work, you have to check whether your NIC supoorts winpcap. And routers may also filter packets, especially when you use Windows.
  2. For Windows users, speed is far slow than rsock on mac/Linux. (500-800KB/s during my test) e.g. On Mac/Linux, rsock can support to watch 1080P youtube video smoothly. For windows users, rsock can only support 720P youtube video.

Exit

ps axu|grep rsock

sudo kill -SIGUSR1 pid # pid is id of rsock. It's 72294 in image above.

Parameters in detail


 -t, --taddr=[addr]  target address. e.g. 8.8.8.8:88,7.7.7.7. Required.
 -l, --ludp=[addr]  local listened udp address. Only valid for client. Required by client.
 -d, --dev=[device]  name of network interface card of Internet.e.g,eth0, en0. rsock can auto detect right device to work on. Use this when the default can't work.
 -h, --help   Display help menu. Not available now.
 -f    json config file
 --lcapIp=[ip]   Internet IP. Can omit the -d if this parameter sepcified. rsock can auto detect right device to work on. Use this when the default can't work.
 --unPath   Local unix domain socket. Not available now.
 -p, --ports=[...]  tcp/udp port list for rsock server. e.g.10001,10010(2 ports); 10001-10010(11 ports); 80,443,10001-10010(12 ports). **NO** white spaces allowed. Default value: 10001-10010
 --duration=[timeSec]  Time for app connection to persist if no data is transfered in the app connection. unit: seconds. defalt 30s
 --hash=[hashKey]  Not for encryption. Only for judgement if data belong to rsock. REPEAT: rsock don't encrypt data. Encryption is done by kcptun.
 --type=[tcp|udp|all]  type of communication. One of tcp, udp or all. Default is tcp.
 --daemon=[1|0]   Run as daemon. 1 yes. 0 no. default 1.
 -v    verbose mode. (Better not change default value. There is an unsolved bug that will cause slow speed right now)
 --log=[path/to/log]  Directory of log. Will create if not exist. Default: /var/log/rsock
 --cap_timeout   timeout of libpcap. Don't change this value if know what it really means.

Principle

  1. Server listens on some ports. (tcp 10001-10010, 10 ports by default)
  2. Client connects to all of server ports.
  3. For each of communications, client send data by libnet to one of server ports, which should have been connected.
  4. Server receive data by libpcap. It's same for server to send data to client. Now they make communication.
  5. For application, local_ip:app_udp_port and server_ip:app_udp_port make a connection。If no data flows thourgh this connection for a period of time(default 30s), it will be closed.
  6. When client receive rst or fin, it will close that real network connection and reconnect to server.

Disadvantage

Under tcp mode, since we don't send/recv data from socket, it will send an ack with 0 length, telling peer next seq it expects. This due to standard. And that will waste bandwith.

Comparison

Comparing objects:rsock, kcptun
Server test environment
digitalocean NY vps. 1G RAM
Client test environment 1. digitalocean Singaport vps.
rsock(tcp only, 11 ports). 1.25M

rsock(udp only, 11 ports). 1.5M

rsock(doc/tcp and udp, 11 ports each. 1.1M

kcptun. The fastest, around 1.5MB.

Client test environment 1. China telecom with 100Mb downloading and 10Mb upload speed.
rsock(tcp only, 11 ports). 1.4M

rsock(udp only, 11 ports. 1.7M

rsock(udp and tcp, 11 ports each)900K. I've tested twice. The speed is slower.

kcptun. extremely fast. Around 2MB.

note: There is no evidence that more ports rsock use, the faster it is. It's mainly determined by your bandwith.

Conclusion

rsock only has 70%-90% speed of kcptun.

Note

If you find no network connection, please check if rsock and kcptun still running.
You can run flowing commands to check:
ps axu|egrep 'kcptun|rsock'

It is strongly recommended that kcptun server and rsock server run in background. For kcptun server, run
nohup sudo -u nobody ./server_linux_amd64 -r ":port1" -l ":port2" -mode fast2 -key aKey >/dev/null 2>&1 &
For rsock server, only need to specify parameter --daemon=1
If servers run normally, try to restart kcptun client(turn shadowsocks on/off, this will restart kcptun).
rsock DOES NOT encrypt data. Encrption happens in app level(kcptun).

Other projects

udp2raw-tunnel
kcptun-raw
icmptunnel

from https://github.com/iceonsun/rsock
https://github.com/iceonsun/rsock/issues/6
-------------

rsock简介以及原理


详细讲解

背景
普通上网是这样的:
normal
其中第一条竖线左边是本机host。第二条竖线右边是server。中间是路由器,防火墙等。http/tcp表示,host和server之间的流量是tcp类型,但协议是http。
缺点:有的网站上不了,比如google。

shadowsocks

为了解决有的网站上不了,于是有了shadowsocks,shadowsocks的工作流程大概是这样的:
shadowsocks
其中 ss_protocol/tcp表示,流浪是tcp类型,但协议是shadowsocks协议,有可能加密过,也有可能没有加密过,且shadowsocks中data字段是上层协议(这里是http)的所有数据。这里host和server之间的流量仍然是tcp。
缺点:出海带宽不稳定,tcp容易丢包,速度慢。

kcptun

为了解决tcp速度慢,于是有了kcptun,kcptun运行着kcp协议。kcp是一个可靠且快速的协议。kcptun的流程大概如下:
kcptun
缺点:运营商会屏蔽udp大流量。

rsock

为了解决udp容易被封,于是有了rsock,rsock的工作流程是这样的:
rsock
下面,详细介绍rsock的工作流程和目的:
  1. rsock_server 监听一个端口(实际是监听一个指定范围的端口,比如10000 到 10010)
  2. rsock_client 正常connect到rsock_server,建立了一个正常的tcp连接(TCP三步握手完成)。建立这个tcp连接的目的后面再讲。
  3. 浏览器把流量传给sslocal,sslocal根据协议加密后发送给kcptun_client,kcptun_client把数据用kcp协议处理过后再加密,然后发给rsock_client
  4. rsock_client把收到的流量通过fake_tcp(伪tcp连接)发送给rsock_server。
注意: 这里发数据是通过libnet(一个跨平台的原始套接字库),收数据是通过libpcap(跨平台的抓包库),数据的收发并没有通过第2步建立的socket。

问题解答

问题1:什么是faketcp?
答:faketcp不存在于操作系统中,只是rsock构造的一条虚拟连接。fake_tcp的中的任意一个数据包,是通过libnet手动构造的(手动指定的srcip:srcport:dstip:dstport),它的格式仍然是tcp的(仅仅是seq,ack不对,其他字段都正确)。
问题2:为什么fake_tcp能通信?
答:
  1. 发数据,并不是通过第2步建立的socket(没有send(socket, buf, len)),而是通过libnet手动构造的一个假tcp数据包,该数据包的所有字段都是手动输入的。其中srcip:srcport:dstip:dstport和第2步建立的tcp的对应数据一样。
  2. 在路由器路由器看来,一个faketcp是数据包是一个正常的tcp包。因为路由器本身无法区分一个包是否是正常的,它只能根据本身的nat表来判断,由srcip:srcport:dstip:dstport构成的这条连接是打开的还是关闭的,如果是打开的,就放转发该数据包(fake_tcp数据包);如果是关闭的,就丢弃该数据。由于在第2步走完了tcp三步握手,所以nat中有该连接对应的表项,所以nat判断该连接是正常的,可以转发数据。
  3. 在操作系统看来,一个faketcp数据包是无效的数据包。因为该数据包的srcip:srcport:dstip:dstport和第2步建立的正常tcp连接是一样的,所以判断该数据包是发送到某个端口的数据包,但里面的seq和内核中记载的seq不匹配,所以会丢弃该数据包。根据tcp协议,系统还会向peer端发送一个ack报文,表示内核中第2步建立的tcp连接所期待的下一个包文。系统不会向peer发送RST,整个连接就不会终端
  4. 收数据,是通过libpcap。libpcap能先于内核抓取到数据,抓取到数据后再发送给上层应用(这里是kcptun)
问题3:不预先建立一条tcp连接可以吗?
答:可以。通常情况下,对于peer发过来的faketcp数据包srcip:srcport:dstip:dstport构成的tcp连接,由于内核中没有该连接的记录,根据tcp协议会发送一个RST报文给peer。NAT收到该报文,发现了RST标记,就会释放掉该连接。造成该链接无法再使用。解决办法是,屏蔽内核固定端口的数据。linux上通过iptable,macOS上通过bpf. 内核接收不到数据,自然也不会发送rst。但libpcap始终能抓取到包。所以始终能收取到数据。
问题4:rsock数据传输是可靠的吗?
答:rsock数据传输是不可靠的,且没有流控。rsock仅仅是把kcptun发送过来的流量转发到rsock peer端。但kcptun的传输是可靠和快速的,所以在shadowsocks/browser看来数据也是可靠和快速的。
问题5:Windows上的传输速度为什么远不如Mac和Linux?
答:这个目前没法改变,Windows系统的回环网络(loopback)丢包太严重。主要数据传输速度变快了以后,kcptun<->rsock这个传输步骤丢包。而Mac/Linux上本地回环网络表现远远好于Windows.

from  https://github.com/iceonsun/rsock/wiki/rsock%E7%AE%80%E4%BB%8B%E4%BB%A5%E5%8F%8A%E5%8E%9F%E7%90%86

No comments:

Post a Comment