Compare commits

..

32 Commits

Author SHA1 Message Date
wangyu-
3bc07d5c86 more log for epoll_wait 2017-11-23 09:56:20 -06:00
wangyu-
f081ab751d do not quit after got EINTR 2017-11-23 09:35:33 -06:00
wangyu-
91097eab5d Create ISSUE_TEMPLATE.md 2017-11-22 18:50:33 -06:00
wangyu-
c22b5e9680 Add files via upload 2017-11-21 14:46:14 -06:00
wangyu-
9162a533d3 changed -h page 2017-11-21 14:46:13 -06:00
wangyu-
b01b087949 Update README.zh-cn.md 2017-11-21 14:46:13 -06:00
wangyu-
51b45c8f39 new option mtu-warn 2017-11-21 14:46:13 -06:00
wangyu-
995ea8c98d Update README.zh-cn.md 2017-11-21 14:46:13 -06:00
wangyu-
aec81eb0c9 Add files via upload 2017-11-21 14:46:13 -06:00
wangyu-
8b59b4afb9 Delete udp2rawopenvpn.PNG 2017-11-21 14:46:13 -06:00
wangyu-
c33bb552cd Update README.zh-cn.md 2017-11-21 14:46:13 -06:00
wangyu-
9516cfe99d increased conv_timeout to 180s 2017-11-21 14:46:13 -06:00
wangyu-
5b1e59cae2 trival 2017-11-21 14:46:13 -06:00
wangyu-
211d7ea4d3 help page 2017-11-21 14:46:12 -06:00
wangyu-
7599d99fcc new option hb-len 2017-11-21 14:46:12 -06:00
wangyu-
706cb0b583 Update README.md 2017-11-21 14:46:12 -06:00
wangyu-
43ae798e77 improve heartbeat 2017-11-21 14:46:12 -06:00
wangyu-
2f12d55229 tuned parameter 2017-11-21 14:46:12 -06:00
wangyu-
0a4555dd42 Update README.md 2017-11-21 14:46:12 -06:00
wangyu-
14ece87bc3 tune parameter 2017-11-21 14:46:12 -06:00
wangyu-
50f682daf4 new option hb-mode 2017-11-21 14:46:12 -06:00
wangyu-
d487ca57f7 changed parameter 2017-11-21 14:46:12 -06:00
wangyu-
482e658858 increase heart beat length 2017-11-21 14:46:12 -06:00
wangyu-
069a9ba2b4 added version.txt into makefile 2017-11-21 14:46:12 -06:00
wangyu-
c591902be1 added missing files 2017-11-21 14:46:12 -06:00
wangyu-
6a825dc51e Update README.zh-cn.md 2017-11-21 14:46:12 -06:00
wangyu-
1bdb6a5720 fixed bug of last few commit, and fixed a bug of bind error 2017-11-21 14:46:11 -06:00
wangyu-
1afe8d7317 more fix 2017-11-21 14:46:11 -06:00
wangyu-
a54a0e269b fix timer of fd64 2017-11-21 14:46:11 -06:00
wangyu-
e8398d0d31 fixed some bug of last commit 2017-11-21 14:46:11 -06:00
wangyu-
dc43cb740b added an assert 2017-11-21 14:46:11 -06:00
wangyu-
2e6be9e159 Update README.md 2017-11-21 14:46:11 -06:00
18 changed files with 121 additions and 46 deletions

6
ISSUE_TEMPLATE.md Normal file
View File

@@ -0,0 +1,6 @@
For English speaking user
https://github.com/wangyu-/UDPspeeder/wiki/Issue-Guide
中文用户请看:
https://github.com/wangyu-/UDPspeeder/wiki/发Issue前请看
(否则Issue可能被忽略或被直接关掉)

View File

@@ -3,11 +3,9 @@
A Tunnel which turns UDP Traffic into Encrypted FakeTCP/UDP/ICMP Traffic by using Raw Socket, helps you Bypass UDP FireWalls(or Unstable UDP Environment). It can defend Replay-Attack and supports Multiplexing. It also acts as a Connection Stabilizer.
When used alone,udp2raw tunnels only UDP traffic. Nevertheless,if you used udp2raw + any UDP-based VPN together,you can tunnel any traffic(include TCP/UDP/ICMP),currently OpenVPN/L2TP/ShadowVPN and [tinyFecVPN](https://github.com/wangyu-/tinyFecVPN) are confirmed to be supported。
![image0](images/image0.PNG)
or
When used alone,udp2raw tunnels only UDP traffic. Nevertheless,if you used udp2raw + any UDP-based VPN together,you can tunnel any traffic(include TCP/UDP/ICMP),currently OpenVPN/L2TP/ShadowVPN and [tinyFecVPN](https://github.com/wangyu-/tinyFecVPN) are confirmed to be supported.
![image_vpn](images/udp2rawopenvpn.PNG)
@@ -16,7 +14,8 @@ or
# Support Platforms
Linux host (including desktop Linux,Android phone/tablet,OpenWRT router,or Raspberry PI) with root access.
For Winodws/MacOS,the 4.4mb virtual image with udp2raw pre-installed has been released,you can load it with Vmware/VirtualBox.The virtual image has been set to auto obtain ip,udp2raw can be run imidiately after boot finished(make sure network mode of virtual machine has been set to bridged)(only udp2raw has to be run under virtual machine,all other programs runs under Windows/MacOS as usual).
For Windows and MacOS You can run udp2raw inside [this](https://github.com/wangyu-/udp2raw-tunnel/releases/download/20171108.0/lede-17.01.2-x86_virtual_machine_image.zip) 7.5mb virtual machine image(make sure network adapter runs at bridged mode).
# Features

View File

@@ -711,7 +711,17 @@ int parse_safer(conn_info_t &conn_info,const char * input,int input_len,char &ty
conn_info.oppsite_roller=roller;
conn_info.last_oppsite_roller_time=get_current_time();
}
conn_info.my_roller++;//increase on a successful recv
if(hb_mode==0)
conn_info.my_roller++;//increase on a successful recv
else if(hb_mode==1)
{
if(type=='h')
conn_info.my_roller++;
}
else
{
assert(0==1);
}
if(after_recv_raw0(conn_info.raw_info)!=0) return -1;

View File

@@ -1,5 +1,5 @@
Udp2raw-tunnel
![image2](/images/image2.PNG)
# Udp2raw-tunnel
![image2](/images/image0.PNG)
udp2raw tunnel通过raw socket给UDP包加上TCP或ICMP header进而绕过UDP屏蔽或QoS或在UDP不稳定的环境下提升稳定性。可以有效防止在使用kcptun或者finalspeed的情况下udp端口被运营商限速。
支持心跳保活、自动重连,重连后会恢复上次连接,在底层掉线的情况下可以保持上层不掉线。同时有加密、防重放攻击、信道复用的功能。
@@ -20,8 +20,17 @@ https://github.com/wangyu-/UDPspeeder
# 支持的平台
Linux主机有root权限。可以是PC、android手机/平板、openwrt路由器、树莓派。主机上最好安装了iptables命令(apt/yum很容易安装)。
在windows和mac上预装了udp2raw的虚拟机镜像已发布可以用Vmware或VirtualBox加载容量4.4mb已经配置好了自动获取网卡ip开机即用稳定性能很好。
udp2raw跑在虚拟机里其他应用照常跑在windows上确保虚拟机网卡工作在桥接模式Vmware player 75mb,VirtualBox 118mb,很容易安装)。
Release中提供了`amd64``x86``arm``mips_be``mips_le`的预编译binary.
##### 对于windows和mac用户
在虚拟机中可以稳定使用udp2raw跑在Linux里其他应用照常跑在window里确保虚拟机网卡工作在桥接模式。可以使用[这个](https://github.com/wangyu-/udp2raw-tunnel/releases/download/20171108.0/lede-17.01.2-x86_virtual_machine_image.zip)虚拟机镜像大小只有7.5mb免去在虚拟机里装系统的麻烦虚拟机自带ssh server可以scp拷贝文件可以ssh进去可以复制粘贴root密码123456。
如果你的网络不允许桥接也是有办法用的具体方法请看wiki。
##### 对于ios和游戏主机用户
可以把udp2raw运行在局域网的其他机器上。最好的办法是买个能刷OpenWrt/LEDE/梅林的路由器把udp2raw运行在路由器上。
# 功能特性
### 把udp流量伪装成tcp /icmp
@@ -51,9 +60,9 @@ NAT 穿透 tcp icmp udp模式都支持nat穿透。
支持Openvz配合finalspeed使用可以在openvz上用tcp模式的finalspeed
支持Openwrt没有编译依赖容易编译到任何平台上。release中提供了ar71xx版本的binary
支持Openwrt没有编译依赖容易编译到任何平台上。
epoll纯异步高并发除了回收过期连接外所有操作的时间复杂度都跟连接数无关。回收过期连接的操做也是柔和进行的不会因为消耗太多cpu时间造成延迟抖动。
epoll实现高并发除了回收过期连接外所有操作的时间复杂度都跟连接数无关。回收过期连接的操做也是柔和进行的不会因为消耗太多cpu时间造成延迟抖动。
### 关键词
突破udp qos,突破udp屏蔽openvpn tcp over tcp problem,openvpn over icmp,udp to icmp tunnel,udp to tcp tunnel,udp via icmp,udp via tcp
@@ -163,14 +172,14 @@ facktcp模式并没有模拟tcp的全部。所以理论上有办法把faketcp和
### `--keep-rule`
定期主动检查iptables如果udp2raw添加的iptables规则丢了就重新添加。在一些iptables可能会被其他程序清空的情况下(比如梅林固件和openwrt的路由器)格外有用。
### `--lower-level`
大部分udp2raw不能连通的情况都是设置了不兼容的iptables造成的。--lower-level选项允许绕过本地iptables。在一些iptables不好改动的情况下尤其有效比如你用的是梅林固件iptables全是固件自己生成的
### `--fifo`
指定一个fifo(named pipe)来向运行中的程序发送命令,例如`--fifo fifo.file`
在client端,可以用`echo reconnect >fifo.file`来强制client换端口重连上层不断线.对Server目前没有效果。
### `--lower-level`
大部分udp2raw不能连通的情况都是设置了不兼容的iptables造成的。--lower-level选项允许绕过本地iptables。在一些iptables不好改动的情况下尤其有效比如你用的是梅林固件iptables全是固件自己生成的
##### 格式
`if_name#dest_mac_adress`,例如 `eth0#00:23:45:67:89:b9``eth0`换成你的出口网卡名。`00:23:45:67:89:b9`换成网关的mac地址如果client和server在同一个局域网内可能不需要网关这时候直接用对方主机的mac地址这个属于罕见的应用场景可以忽略

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 58 KiB

1
images/wiki/111 Normal file
View File

@@ -0,0 +1 @@

BIN
images/wiki/mac_nat_vb1.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
images/wiki/mac_nat_vb2.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
images/wiki/mac_nat_vb3.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
images/wiki/mac_nat_vb4.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
images/wiki/windows_nat.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -7,7 +7,9 @@
#include "encrypt.h"
#include "fd_manager.h"
int mtu_warn=1375;//if a packet larger than mtu warn is receviced,there will be a warning
char hb_buf[buf_len];
int server_on_raw_recv_pre_ready(conn_info_t &conn_info,char * ip_port,u32_t tmp_oppsite_const_id);
int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,char *data,int data_len);
@@ -225,11 +227,6 @@ int client_on_timer(conn_info_t &conn_info) //for client. called when a timer is
return 0;
}
if(get_current_time()-conn_info.last_hb_sent_time<heartbeat_interval)
{
return 0;
}
if(get_current_time()- conn_info.last_oppsite_roller_time>client_conn_uplink_timeout)
{
conn_info.state.client_current_state=client_idle;
@@ -237,10 +234,20 @@ int client_on_timer(conn_info_t &conn_info) //for client. called when a timer is
mylog(log_info,"state back to client_idle from client_ready bc of client-->server direction timeout\n");
}
if(get_current_time()-conn_info.last_hb_sent_time<heartbeat_interval)
{
return 0;
}
mylog(log_debug,"heartbeat sent <%x,%x>\n",conn_info.oppsite_id,conn_info.my_id);
send_safer(conn_info,'h',"",0);/////////////send
if(hb_mode==0)
send_safer(conn_info,'h',hb_buf,0);/////////////send
else
send_safer(conn_info,'h',hb_buf,hb_len);
conn_info.last_hb_sent_time=get_current_time();
return 0;
}
@@ -282,8 +289,10 @@ int server_on_timer_multi(conn_info_t &conn_info,char * ip_port) //for server.
return 0;
}
send_safer(conn_info,'h',"",0); /////////////send
if(hb_mode==0)
send_safer(conn_info,'h',hb_buf,0); /////////////send
else
send_safer(conn_info,'h',hb_buf,hb_len);
conn_info.last_hb_sent_time=get_current_time();
mylog(log_debug,"heart beat sent<%x,%x>\n",conn_info.my_id,conn_info.oppsite_id);
@@ -429,9 +438,9 @@ int client_on_raw_recv(conn_info_t &conn_info) //called when raw fd received a p
conn_info.last_oppsite_roller_time=conn_info.last_hb_recv_time;
client_on_timer(conn_info);
}
if(data_len==0&&type=='h')
if(data_len>=0&&type=='h')
{
mylog(log_debug,"[hb]heart beat received\n");
mylog(log_debug,"[hb]heart beat received,oppsite_roller=%d\n",int(conn_info.oppsite_roller));
conn_info.last_hb_recv_time=get_current_time();
return 0;
}
@@ -439,7 +448,8 @@ int client_on_raw_recv(conn_info_t &conn_info) //called when raw fd received a p
{
mylog(log_trace,"received a data from fake tcp,len:%d\n",data_len);
conn_info.last_hb_recv_time=get_current_time();
if(hb_mode==0)
conn_info.last_hb_recv_time=get_current_time();
//u32_t tmp_conv_id= ntohl(* ((u32_t *)&data[0]));
u32_t tmp_conv_id;
@@ -773,7 +783,7 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
return 0;
}*/
if (type == 'h' && data_len == 0) {
if (type == 'h' && data_len >= 0) {
//u32_t tmp = ntohl(*((u32_t *) &data[sizeof(u32_t)]));
mylog(log_debug,"[%s][hb]received hb \n",ip_port);
conn_info.last_hb_recv_time = get_current_time();
@@ -787,7 +797,8 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
tmp_conv_id=ntohl(tmp_conv_id);
conn_info.last_hb_recv_time = get_current_time();
if(hb_mode==0)
conn_info.last_hb_recv_time = get_current_time();
mylog(log_trace, "conv:%u\n", tmp_conv_id);
if (!conn_info.blob->conv_manager.is_conv_used(tmp_conv_id)) {
@@ -913,11 +924,14 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info,char * ip_port,u32_t tmp
//my_id=conn_info.my_id;
//oppsite_id=conn_info.oppsite_id;
conn_info.last_hb_recv_time = get_current_time();
conn_info.last_hb_sent_time = conn_info.last_hb_recv_time;//=get_current_time()
send_safer(conn_info, 'h',"", 0); /////////////send
if(hb_mode==0)
send_safer(conn_info,'h',hb_buf,0);/////////////send
else
send_safer(conn_info,'h',hb_buf,hb_len);
mylog(log_info, "[%s]changed state to server_ready\n",ip_port);
conn_info.blob->anti_replay.re_init();
@@ -977,8 +991,14 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info,char * ip_port,u32_t tmp
//ori_conn_info.state.server_current_state=server_ready;
ori_conn_info.recover(conn_info);
send_safer(ori_conn_info, 'h',"", 0);
//send_safer(ori_conn_info, 'h',hb_buf, hb_len);
//ori_conn_info.blob->anti_replay.re_init();
if(hb_mode==0)
send_safer(ori_conn_info,'h',hb_buf,0);/////////////send
else
send_safer(ori_conn_info,'h',hb_buf,hb_len);
ori_conn_info.last_hb_recv_time=get_current_time();
@@ -1176,13 +1196,13 @@ int client_event_loop()
if (nfds < 0) { //allow zero
if(errno==EINTR )
{
mylog(log_info,"epoll interrupted by signal\n");
mylog(log_info,"epoll interrupted by signal,continue\n");
//close(fifo_fd);
myexit(0);
//myexit(0);
}
else
{
mylog(log_fatal,"epoll_wait return %d\n", nfds);
mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno));
myexit(-1);
}
}
@@ -1420,12 +1440,12 @@ int server_event_loop()
if (nfds < 0) { //allow zero
if(errno==EINTR )
{
mylog(log_info,"epoll interrupted by signal\n");
myexit(0);
mylog(log_info,"epoll interrupted by signal,continue\n");
//myexit(0);
}
else
{
mylog(log_fatal,"epoll_wait return %d\n", nfds);
mylog(log_fatal,"epoll_wait return %d,%s\n", nfds,strerror(errno));
myexit(-1);
}
}

View File

@@ -13,6 +13,12 @@
#include "fd_manager.h"
int hb_mode=1;
int hb_len=1200;
int mtu_warn=1375;//if a packet larger than mtu warn is receviced,there will be a warning
fd_manager_t fd_manager;
char local_ip[100]="0.0.0.0", remote_ip[100]="255.255.255.255",source_ip[100]="0.0.0.0";//local_ip is for -l option,remote_ip for -r option,source for --source-ip
@@ -149,6 +155,8 @@ void print_help()
printf(" the parameter automatically,specify it manually if 'auto' failed\n");
printf(" --gen-add generate iptables rule and add it permanently,then exit.overrides -g\n");
printf(" --keep-rule monitor iptables and auto re-add if necessary.implys -a\n");
printf(" --hb-len <number> length of heart-beat packet, >=0 and <=1500\n");
printf(" --mtu-warn <number> mtu warning threshold, unit:byte, default:1375\n");
printf(" --clear clear any iptables rules added by this program.overrides everything\n");
printf(" -h,--help print this help message\n");
@@ -247,6 +255,9 @@ void process_arg(int argc, char *argv[]) //process all options
{"force-sock-buf", no_argument, 0, 1},
{"random-drop", required_argument, 0, 1},
{"fifo", required_argument, 0, 1},
{"hb-mode", required_argument, 0, 1},
{"hb-len", required_argument, 0, 1},
{"mtu-warn", required_argument, 0, 1},
{NULL, 0, 0, 0}
};
@@ -589,7 +600,24 @@ void process_arg(int argc, char *argv[]) //process all options
{
mylog(log_info,"configuration loaded from %s\n",optarg);
}
else if(strcmp(long_options[option_index].name,"hb-mode")==0)
{
sscanf(optarg,"%d",&hb_mode);
assert(hb_mode==0||hb_mode==1);
mylog(log_info,"hb_mode =%d \n",hb_mode);
}
else if(strcmp(long_options[option_index].name,"hb-len")==0)
{
sscanf(optarg,"%d",&hb_len);
assert(hb_len>=0&&hb_len<=1500);
mylog(log_info,"hb_len =%d \n",hb_len);
}
else if(strcmp(long_options[option_index].name,"mtu-warn")==0)
{
sscanf(optarg,"%d",&mtu_warn);
assert(mtu_warn>0);
mylog(log_info,"mtu_warn=%d \n",mtu_warn);
}
else
{
mylog(log_warn,"ignored unknown long option ,option_index:%d code:<%x>\n",option_index, optopt);

16
misc.h
View File

@@ -13,7 +13,9 @@
#include "log.h"
#include "network.h"
extern int hb_mode;
extern int hb_len;
extern int mtu_warn;
const u32_t max_handshake_conn_num=10000;
const u32_t max_ready_conn_num=1000;
@@ -25,22 +27,22 @@ const u32_t client_retry_interval=1000;//ms
const u32_t server_handshake_timeout=client_handshake_timeout+5000;// this should be longer than clients. client retry initially ,server retry passtively
const int conv_clear_ratio=10; //conv grabage collecter check 1/10 of all conv one time
const int conn_clear_ratio=30;
const int conv_clear_ratio=30; //conv grabage collecter check 1/30 of all conv one time
const int conn_clear_ratio=50;
const int conv_clear_min=1;
const int conn_clear_min=1;
const u32_t conv_clear_interval=3000;//ms
const u32_t conn_clear_interval=3000;//ms
const u32_t conv_clear_interval=1000;//ms
const u32_t conn_clear_interval=1000;//ms
const i32_t max_fail_time=0;//disable
const u32_t heartbeat_interval=1000;//ms
const u32_t heartbeat_interval=600;//ms
const u32_t timer_interval=400;//ms. this should be smaller than heartbeat_interval and retry interval;
const uint32_t conv_timeout=120000; //ms. 120 second
const uint32_t conv_timeout=180000; //ms. 120 second
//const u32_t conv_timeout=30000; //for test
const u32_t client_conn_timeout=10000;//ms.