This commit is contained in:
wangyu- 2017-11-06 03:17:38 -06:00
commit fde2329528
10 changed files with 225 additions and 105 deletions

View File

@ -13,8 +13,17 @@ or
[简体中文](/doc/README.zh-cn.md)(内容更丰富)
###### Note
You can use udp2raw with UDPspeeder together to bypass UDP firewalls.
udp2rawhttps://github.com/wangyu-/udp2raw-tunnel
You can use udp2raw with UDPspeeder together to get better speed on some ISP with UDP QoS(UDP throttling).
udp2raw's repo
https://github.com/wangyu-/udp2raw-tunnel
You can also try tinyFecVPN, a lightweight high-performance VPN with build-in FEC support:
tinyFecVPN's repo:
https://github.com/wangyu-/tinyFecVPN
# Efficacy
@ -73,7 +82,7 @@ Now connecting to UDP port 3333 at the client side is equivalent to connecting t
`-f20:10` means sending 10 redundant packets for every 20 original packets.
`-k` enables simple XOR encryption to confuse DPI(Deep Packet Inspection)
`-k` enables simple XOR encryption
To run stably, pay attention to MTU.

View File

@ -260,6 +260,39 @@ unsigned short csum(const unsigned short *ptr,int nbytes) {
return(answer);
}
unsigned short tcp_csum(const pseudo_header & ph,const unsigned short *ptr,int nbytes) {//works both for big and little endian
register long sum;
unsigned short oddbyte;
register short answer;
sum=0;
unsigned short * tmp= (unsigned short *)&ph;
for(int i=0;i<6;i++)
{
sum+=*tmp++;
}
while(nbytes>1) {
sum+=*ptr++;
nbytes-=2;
}
if(nbytes==1) {
oddbyte=0;
*((u_char*)&oddbyte)=*(u_char*)ptr;
sum+=oddbyte;
}
sum = (sum>>16)+(sum & 0xffff);
sum = sum + (sum>>16);
answer=(short)~sum;
return(answer);
}
int set_buf_size(int fd,int socket_buf_size,int force_socket_buf)
{
if(force_socket_buf)

View File

@ -176,6 +176,13 @@ struct fd_info_t
ip_port_t ip_port;
};
struct pseudo_header {
u_int32_t source_address;
u_int32_t dest_address;
u_int8_t placeholder;
u_int8_t protocol;
u_int16_t tcp_length;
};
u64_t get_current_time();
u64_t get_current_time_us();
@ -209,6 +216,7 @@ void setnonblocking(int sock);
int set_buf_size(int fd,int socket_buf_size,int force_socket_buf=0);
unsigned short csum(const unsigned short *ptr,int nbytes);
unsigned short tcp_csum(const pseudo_header & ph,const unsigned short *ptr,int nbytes);
void signal_handler(int sig);
int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len);

View File

@ -11,9 +11,21 @@
![image0](/images/Capture2.PNG)
另外可以和udp2raw串联使用在加速的同时把UDP伪装成TCP防止UDP被运营商QOS或屏蔽。udp2raw: https://github.com/wangyu-/udp2raw-tunnel
对于某些运营商UDPspeeder跟udp2raw配合可以达到更好的速度udp2raw负责把UDP伪装成TCP来绕过运营商的UDP限速。
udp2raw的repo:
https://github.com/wangyu-/udp2raw-tunnel
如果你嫌UDPspeeder+OpenVPN麻烦你可以尝试tinyFecVPN一个集成了UDPspeeder功能的VPN
tinyFecVPN的repo:
https://github.com/wangyu-/tinyFecVPN
#### 效果
![image0](/images/Capture8.PNG)
![image0](/images/cn/ping_compare_cn.PNG)
![image0](/images/cn/scp_compare.PNG)
#### 原理简介
@ -67,7 +79,7 @@ https://github.com/wangyu-/UDPspeeder/releases
`-f20:10` 表示对每20个原始数据发送10个冗余包。`-f20:10``-f 20:10`都是可以的空格可以省略对于所有的单字节option都是如此。对于双字节option例如后面的`--mode 0``--mtu 1200`,空格不可以省略。
`-k` 指定一个字符串,server/client间所有收发的包都会被异或改变协议特征防止UDPspeeder的协议被运营商针对。
`-k` 指定一个字符串,开启简单的异或加密
###### 注意
@ -165,8 +177,6 @@ mode 0模式允许你发送的数据包大小超过物理接口的MTU而几乎
##### `--disable-obscure`
UDPspeeder默认情况下会对每个发出的数据包随机填充和异或一些字节(4~32字节)这样通过抓包难以发现你发了冗余数据防止VPS被封。这个功能只是为了小心谨慎即使你关掉这个功能基本上也没问题关掉可以省一些带宽和CPU。
##### `-q,--queue-len`
编码器在做FEC前最多积攒多少个数据包只对mode 0有效。除非是使用下文`V2版如何多倍发包`里面提到的用法,不建议改动。
#### `--fifo` option
用fifo(命名管道)向运行中的程序发送command。例如`--fifo fifo.file`可用的command有
```
@ -190,16 +200,16 @@ echo mode 0 > fifo.file
### V2版如何多倍发包
只要在设置-f参数时把x设置为1fec算法就退化为多倍发包了。例如-f1:1表示2倍发包-f1:2表示3倍发包以此类推。另外可以加上`--mode 0 -q1`参数防止fec编码器试图积攒和合并数据获得最低的延迟。
只要在设置-f参数时把x设置为1fec算法就退化为多倍发包了。例如-f1:1表示2倍发包-f1:2表示3倍发包以此类推。另外建议加上"--mode 1"参数防止fec编码器试图积攒和合并数据获得最低的延迟。
2倍发包的完整参数
```
./speederv2 -s -l0.0.0.0:4096 -r127.0.0.1:7777 -f1:1 -k "passwd" --mode 0 -q1
./speederv2 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -f1:1 -k "passwd" --mode 0 -q1
./speederv2 -s -l0.0.0.0:4096 -r127.0.0.1:7777 -f1:1 -k "passwd" --mode 1
./speederv2 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -f1:1 -k "passwd" --mode 1
```
使用了`--mode 0 -q1`以后,`--timeout`选项不起作用,所以不用调。
使用了`--mode 1`以后,`--timeout`选项不起作用,所以不用调。
如果你只需要多倍发包可以直接用回V1版V1版配置更简单占用内存更小而且经过了几个月的考验很稳定。
@ -227,9 +237,9 @@ FEC算法很吃CPU初次使用建议关注UDPspeeder的CPU占用。如果CPU
### 为什么使用之后效果反而变差了?
有可能是你用了mode 0参数而又没调好参数。
有可能是你用了`--mode 0`参数,而又没调好参数。
如果你没有使用mode 0而确实效果变差了那很可能是因为你的运营商对UDP有限制。一般看视频和下载都是TCP流量而用UDPspeeder中转后流量变成了UDP流量如果运营商对UDP做了限制就可能导致效果比不用还差。用udp2raw可以解决udp2raw: https://github.com/wangyu-/udp2raw-tunnel
如果你没有使用`--mode 0`而确实效果变差了那很可能是因为你的运营商对UDP有限制。一般看视频和下载都是TCP流量而用UDPspeeder中转后流量变成了UDP流量如果运营商对UDP做了限制就可能导致效果比不用还差。用udp2raw可以解决udp2raw: https://github.com/wangyu-/udp2raw-tunnel
### UDPspeeder和BBR/锐速配合
@ -255,12 +265,18 @@ UDPspeeder和Kcptun配合UDPspeeder和Kcptun可以并联也可以串联。
#### UDPspeeder + OpenVPN加速任何流量也适用于其他VPN
![image0](/images/Capture2.PNG)
具体配置见,[UDPspeeder + openvpn config guide](/doc/udpspeeder_openvpn.md).
可以和BBR/锐速叠加不过BBR/锐速部署在VPS上只对从本地到VPS的流量有效对从本地到第三方服务器的流量无效。
需要在服务端开启ipforward和NAT。在客户端改路由表可以手动修改也可以由OpenVPN的redirect-gateway选项自动加好
Linux具体配置: [UDPspeeder + openvpn config guide](/doc/udpspeeder_openvpn.md).
Windows具体配置: [win10系统UDPspeeder+OpenVPN的完整设置](https://github.com/wangyu-/UDPspeeder/wiki/win10系统UDPspeeder-OpenVPN的完整设置)
如果UDPspeeder + OpenVPN对你来说显得太麻烦了你可以尝试一下tinyFecVPN,一个集成了UDPspeeder功能的VPN:
https://github.com/wangyu-/tinyFecVPN/
#### UDPspeeder + kcptun/finalspeed + $*** 同时加速tcp和udp流量
如果你需要用加速的tcp看视频和下载文件这样效果可能比没有BBR的UDPspeeder+vpn方案更好。另外如果你需要玩游戏但是嫌配VPN麻烦也可以用这种方案。
![image0](/images/cn/speeder_kcptun.PNG)
@ -281,9 +297,9 @@ run at client side:
这就是全部的命令了。issue里有很多人困惑于怎么把tcp和udp流量"分开",其实很简单就可以做到。
如果只需要加速UDP不需要加速TCP可以把kcptun换成其他的任意端口转发方式比如ncat/socat/ssh tunnel/iptables。
如果只需要加速UDP不需要加速TCP可以把kcptun换成其他的任意端口转发方式比如ncat/socat/ssh tunnel/iptables/[tinyPortMapper](https://github.com/wangyu-/tinyPortMapper/releases)
另外如果没有kcptun只有BBR/锐速的话也可以把kcptun换成ncat/socat/ssh tunnel/iptables。这样TCP流量由锐速/BBR加速UDP由UDPspeeder加速。
另外如果没有kcptun只有BBR/锐速的话也可以把kcptun换成ncat/socat/ssh tunnel/iptables/[tinyPortMapper](https://github.com/wangyu-/tinyPortMapper/releases)。这样TCP流量由锐速/BBR加速UDP由UDPspeeder加速。
#### UDPspeeder + openvpn + $*** 混合方案也适用于其他VPN
也是我正在用的方案。优点是可以随时在vpn和$\*\*\*方案间快速切换。
@ -295,6 +311,20 @@ run at client side:
可以和BBR/锐速叠加BBR/锐速只要部署在VPS上就有效。
也可以用[tinyFecVPN](https://github.com/wangyu-/tinyFecVPN/) + $\*\*\* ,配置起来更简单。
# 应用实例
#### win10系统UDPspeeder+OpenVPN的完整设置
https://github.com/wangyu-/UDPspeeder/wiki/win10系统UDPspeeder-OpenVPN的完整设置
#### 用树莓派做路由器,搭建透明代理,加速游戏主机的网络
https://github.com/wangyu-/UDPspeeder/wiki/用树莓派做路由器,搭建透明代理,加速游戏主机的网络
# 编译教程
暂时先参考udp2raw的这篇教程几乎一样的过程。

View File

@ -100,3 +100,8 @@ or
ip route add 44.55.66.77 dev XXX
```
(run at client side)
##### Other Info
You can also use tinyFecVPN,a lightweight VPN with build-in FEC support:
https://github.com/wangyu-/tinyFecVPN

View File

@ -218,10 +218,14 @@ int fec_encode_manager_t::input(char *s,int len/*,int &is_first_packet*/)
//int counter_back=counter;
assert(fec_mode==0||fec_mode==1);
if(fec_mode==0&& s!=0 &&counter==0&&blob_encode.get_shard_len(fec_data_num,len)>fec_mtu)
if(fec_mode==0&& s!=0 &&counter==0)
{
mylog(log_warn,"message too long len=%d,ignored\n",len);
return -1;
int out_len=blob_encode.get_shard_len(fec_data_num,len);
if(out_len>fec_mtu)
{
mylog(log_warn,"message too long ori_len=%d out_len=%d fec_mtu=%d,ignored\n",len,out_len,fec_mtu);
return -1;
}
}
if(fec_mode==1&&s!=0&&len>fec_mtu)
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -10,9 +10,69 @@
#include "misc.h"
#include "tunnel.h"
//#include "tun_dev.h"
#include "git_version.h"
using namespace std;
static void print_help()
{
char git_version_buf[100]={0};
strncpy(git_version_buf,gitversion,10);
printf("UDPspeeder V2\n");
printf("git version: %s ",git_version_buf);
printf("build date: %s %s\n",__DATE__,__TIME__);
printf("repository: https://github.com/wangyu-/UDPspeeder\n");
printf("\n");
printf("usage:\n");
printf(" run as client: ./this_program -c -l local_listen_ip:local_port -r server_ip:server_port [options]\n");
printf(" run as server: ./this_program -s -l server_listen_ip:server_port -r remote_ip:remote_port [options]\n");
printf("\n");
printf("common options, must be same on both sides:\n");
printf(" -k,--key <string> key for simple xor encryption. if not set, xor is disabled\n");
printf("main options:\n");
printf(" -f,--fec x:y forward error correction, send y redundant packets for every x packets\n");
printf(" --timeout <number> how long could a packet be held in queue before doing fec, unit: ms, default: 8ms\n");
printf(" --mode <number> fec-mode,available values: 0, 1; 0 cost less bandwidth, 1 cost less latency(default)\n");
printf(" --report <number> turn on send/recv report, and set a period for reporting, unit: s\n");
printf("advanced options:\n");
printf(" --mtu <number> mtu. for mode 0, the program will split packet to segment smaller than mtu_value.\n");
printf(" for mode 1, no packet will be split, the program just check if the mtu is exceed.\n");
printf(" default value: 1250\n");
printf(" -j,--jitter <number> simulated jitter. randomly delay first packet for 0~<number> ms, default value: 0.\n");
printf(" do not use if you dont know what it means.\n");
printf(" -i,--interval <number> scatter each fec group to a interval of <number> ms, to protect burst packet loss.\n");
printf(" default value: 0. do not use if you dont know what it means.\n");
printf(" --random-drop <number> simulate packet loss, unit: 0.01%%. default value: 0\n");
printf(" --disable-obscure <number> disable obscure, to save a bit bandwidth and cpu\n");
// printf(" --disable-xor <number> disable xor\n");
printf("developer options:\n");
printf(" --fifo <string> use a fifo(named pipe) for sending commands to the running program, so that you\n");
printf(" can change fec encode parameters dynamically, check readme.md in repository for\n");
printf(" supported commands.\n");
printf(" -j ,--jitter jmin:jmax similiar to -j above, but create jitter randomly between jmin and jmax\n");
printf(" -i,--interval imin:imax similiar to -i above, but scatter randomly between imin and imax\n");
printf(" -q,--queue-len <number> max fec queue len, only for mode 0\n");
printf(" --decode-buf <number> size of buffer of fec decoder,u nit: packet, default: 2000\n");
printf(" --fix-latency <number> try to stabilize latency, only for mode 0\n");
printf(" --delay-capacity <number> max number of delayed packets\n");
printf(" --disable-fec <number> completely disable fec, turn the program into a normal udp tunnel\n");
printf(" --sock-buf <number> buf size for socket, >=10 and <=10240, unit: kbyte, default: 1024\n");
printf("log and help options:\n");
printf(" --log-level <number> 0: never 1: fatal 2: error 3: warn \n");
printf(" 4: info (default) 5: debug 6: trace\n");
printf(" --log-position enable file name, function name, line number in log\n");
printf(" --disable-color disable log color\n");
printf(" -h,--help print this help message\n");
//printf("common options,these options must be same on both side\n");
}
int main(int argc, char *argv[])
{
//working_mode=tunnel_mode;
@ -25,6 +85,22 @@ int main(int argc, char *argv[])
assert(sizeof(i16_t)==2);
dup2(1, 2); //redirect stderr to stdout
int i, j, k;
if (argc == 1)
{
print_help();
myexit( -1);
}
for (i = 0; i < argc; i++)
{
if(strcmp(argv[i],"-h")==0||strcmp(argv[i],"--help")==0)
{
print_help();
myexit(0);
}
}
process_arg(argc,argv);
delay_manager.set_capacity(delay_capacity);

113
misc.cpp
View File

@ -40,12 +40,18 @@ int time_mono_test=0;
int delay_capacity=0;
char sub_net[100]="10.0.0.0";
char sub_net[100]="10.22.22.0";
u32_t sub_net_uint32=0;
char tun_dev[100]="";
int keep_reconnect=0;
int tun_mtu=1500;
int mssfix=1;
int from_normal_to_fec(conn_info_t & conn_info,char *data,int len,int & out_n,char **&out_arr,int *&out_len,my_time_t *&out_delay)
{
@ -566,15 +572,14 @@ void process_arg(int argc, char *argv[])
{"jitter", required_argument, 0,'j'},
{"fifo", required_argument, 0, 1},
{"sub-net", required_argument, 0, 1},
{"tun-dev", optional_argument, 0, 1},
{"tun-dev", required_argument, 0, 1},
{"tun-mtu", required_argument, 0, 1},
{"disable-mssfix", no_argument, 0, 1},
{"keep-reconnect", no_argument, 0, 1},
{NULL, 0, 0, 0}
};
int option_index = 0;
if (argc == 1)
{
print_help();
myexit( -1);
}
for (i = 0; i < argc; i++)
{
if(strcmp(argv[i],"--unit-test")==0)
@ -583,14 +588,7 @@ void process_arg(int argc, char *argv[])
myexit(0);
}
}
for (i = 0; i < argc; i++)
{
if(strcmp(argv[i],"-h")==0||strcmp(argv[i],"--help")==0)
{
print_help();
myexit(0);
}
}
for (i = 0; i < argc; i++)
{
if(strcmp(argv[i],"--log-level")==0)
@ -621,11 +619,6 @@ void process_arg(int argc, char *argv[])
}
log_bare(log_info, "\n");
if (argc == 1)
{
print_help();
myexit(-1);
}
int no_l = 1, no_r = 1;
while ((opt = getopt_long(argc, argv, "l:r:hcsk:j:f:p:n:i:q:",long_options,&option_index)) != -1)
@ -884,6 +877,11 @@ void process_arg(int argc, char *argv[])
mylog(log_info,"fifo_file =%s \n",fifo_file);
}
else if(strcmp(long_options[option_index].name,"keep-reconnect")==0)
{
keep_reconnect=1;
mylog(log_info,"keep_reconnect enabled\n");
}
else if(strcmp(long_options[option_index].name,"sub-net")==0)
{
sscanf(optarg,"%s",sub_net);
@ -892,14 +890,22 @@ void process_arg(int argc, char *argv[])
}
else if(strcmp(long_options[option_index].name,"tun-dev")==0)
{
if(optarg!=0)
{
sscanf(optarg,"%s",tun_dev);
mylog(log_info,"tun_dev =%s \n",tun_dev);
}
sscanf(optarg,"%s",tun_dev);
mylog(log_info,"tun_dev=%s\n",tun_dev);
mylog(log_info,"running at tun-dev mode\n");
working_mode=tun_dev_mode;
}
else if(strcmp(long_options[option_index].name,"tun-mtu")==0)
{
sscanf(optarg,"%d",&tun_mtu);
mylog(log_warn,"changed tun_mtu,tun_mtu=%d\n",tun_mtu);
}
else if(strcmp(long_options[option_index].name,"disable-mssfix")==0)
{
mssfix=0;
mylog(log_warn,"mssfix disabled\n");
}
else
{
mylog(log_fatal,"unknown option\n");
@ -959,60 +965,3 @@ void process_arg(int argc, char *argv[])
}
void print_help()
{
char git_version_buf[100]={0};
strncpy(git_version_buf,gitversion,10);
printf("UDPspeeder V2\n");
printf("git version: %s ",git_version_buf);
printf("build date: %s %s\n",__DATE__,__TIME__);
printf("repository: https://github.com/wangyu-/UDPspeeder\n");
printf("\n");
printf("usage:\n");
printf(" run as client: ./this_program -c -l local_listen_ip:local_port -r server_ip:server_port [options]\n");
printf(" run as server: ./this_program -s -l server_listen_ip:server_port -r remote_ip:remote_port [options]\n");
printf("\n");
printf("common options, must be same on both sides:\n");
printf(" -k,--key <string> key for simple xor encryption. if not set, xor is disabled\n");
printf("main options:\n");
printf(" -f,--fec x:y forward error correction, send y redundant packets for every x packets\n");
printf(" --timeout <number> how long could a packet be held in queue before doing fec, unit: ms, default: 8ms\n");
printf(" --mode <number> fec-mode,available values: 0, 1; 0 cost less bandwidth, 1 cost less latency(default)\n");
printf(" --report <number> turn on send/recv report, and set a period for reporting, unit: s\n");
printf("advanced options:\n");
printf(" --mtu <number> mtu. for mode 0, the program will split packet to segment smaller than mtu_value.\n");
printf(" for mode 1, no packet will be split, the program just check if the mtu is exceed.\n");
printf(" default value: 1250\n");
printf(" -j,--jitter <number> simulated jitter. randomly delay first packet for 0~<number> ms, default value: 0.\n");
printf(" do not use if you dont know what it means.\n");
printf(" -i,--interval <number> scatter each fec group to a interval of <number> ms, to protect burst packet loss.\n");
printf(" default value: 0. do not use if you dont know what it means.\n");
printf(" --random-drop <number> simulate packet loss, unit: 0.01%%. default value: 0\n");
printf(" --disable-obscure <number> disable obscure, to save a bit bandwidth and cpu\n");
// printf(" --disable-xor <number> disable xor\n");
printf("developer options:\n");
printf(" --fifo <string> use a fifo(named pipe) for sending commands to the running program, so that you\n");
printf(" can change fec encode parameters dynamically, check readme.md in repository for\n");
printf(" supported commands.\n");
printf(" -j ,--jitter jmin:jmax similiar to -j above, but create jitter randomly between jmin and jmax\n");
printf(" -i,--interval imin:imax similiar to -i above, but scatter randomly between imin and imax\n");
printf(" -q,--queue-len <number> max fec queue len, only for mode 0\n");
printf(" --decode-buf <number> size of buffer of fec decoder,u nit: packet, default: 2000\n");
printf(" --fix-latency <number> try to stabilize latency, only for mode 0\n");
printf(" --delay-capacity <number> max number of delayed packets\n");
printf(" --disable-fec <number> completely disable fec, turn the program into a normal udp tunnel\n");
printf(" --sock-buf <number> buf size for socket, >=10 and <=10240, unit: kbyte, default: 1024\n");
printf("log and help options:\n");
printf(" --log-level <number> 0: never 1: fatal 2: error 3: warn \n");
printf(" 4: info (default) 5: debug 6: trace\n");
printf(" --log-position enable file name, function name, line number in log\n");
printf(" --disable-color disable log color\n");
printf(" -h,--help print this help message\n");
//printf("common options,these options must be same on both side\n");
}

10
misc.h
View File

@ -13,7 +13,7 @@
#include "fd_manager.h"
#include "delay_manager.h"
#include "fec_manager.h"
#include "git_version.h"
extern char fifo_file[1000];
@ -46,6 +46,12 @@ extern int time_mono_test;
extern int delay_capacity;
extern int keep_reconnect;
extern int tun_mtu;
extern int mssfix;
int from_normal_to_fec(conn_info_t & conn_info,char *data,int len,int & out_n,char **&out_arr,int *&out_len,my_time_t *&out_delay);
int from_fec_to_normal(conn_info_t & conn_info,char *data,int len,int & out_n,char **&out_arr,int *&out_len,my_time_t *&out_delay);
@ -56,7 +62,7 @@ int handle_command(char *s);
int unit_test();
void print_help();
//void print_help();
void process_arg(int argc, char *argv[]);