Compare commits

...

21 Commits

Author SHA1 Message Date
wangyu-
4c92c29948 added version.txt into makefile 2017-11-03 01:04:59 -05:00
wangyu-
cadb142455 added missing files 2017-11-02 19:49:04 -05:00
wangyu-
fcb418f5ea Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-11-01 23:01:23 -05:00
wangyu-
63eb7f1f7f fixed bug of last few commit, and fixed a bug of bind error 2017-11-01 08:25:50 -05:00
wangyu-
66b2bb87c5 Update README.md 2017-10-30 20:25:17 -07:00
wangyu-
6b27f8624d Update README.md 2017-10-30 20:24:53 -07:00
wangyu-
ce7b89f6b6 Update README.md 2017-10-30 20:22:42 -07:00
wangyu-
a0bfa86699 Update README.zh-cn.md 2017-10-30 08:42:38 -07:00
wangyu-
e332cabfed Update README.zh-cn.md 2017-10-30 08:42:21 -07:00
wangyu-
9798bf496a Update README.zh-cn.md 2017-10-30 08:41:54 -07:00
wangyu-
7aa4b8745e trival 2017-10-30 08:59:47 -05:00
wangyu-
ea6a41ebb3 more fix 2017-10-30 08:37:53 -05:00
wangyu-
77ba1161f5 fix timer of fd64 2017-10-30 08:19:21 -05:00
wangyu-
7858c4d832 fixed some bug of last commit 2017-10-30 08:02:23 -05:00
wangyu-
71152ffbe3 added an assert 2017-10-30 07:29:40 -05:00
wangyu-
b06e979dc8 Merge branch 'master' of https://github.com/wangyu-/udp2raw-tunnel 2017-10-30 07:24:26 -05:00
wangyu-
5300f98b0a Update README.md 2017-10-25 21:10:26 -07:00
wangyu-
063d133463 Update README.md 2017-10-25 21:09:59 -07:00
wangyu-
4c88df9c0e Add files via upload 2017-10-26 12:09:09 +08:00
wangyu-
52cb20ec20 Update README.md 2017-10-25 21:04:18 -07:00
wangyu-
7aede9edd0 Update README.md 2017-10-25 21:00:10 -07:00
14 changed files with 166 additions and 52 deletions

View File

@@ -1,9 +1,15 @@
# Udp2raw-tunnel
![image0](images/image0.PNG)
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.
It can tunnel any traffic when used together with a UDP-based VPN(such as OpenVPN).Check [this link](https://github.com/wangyu-/udp2raw-tunnel#tunneling-any-traffic-via-raw-traffic-by-using-udp2raw-openvpn) for more info.
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
![image_vpn](images/udp2rawopenvpn.PNG)
[简体中文](/doc/README.zh-cn.md)
@@ -226,7 +232,7 @@ raw_mode: faketcp cipher_mode: aes128cbc  auth_mode: md5
# Application
## Tunneling any traffic via raw traffic by using udp2raw +openvpn
![image_vpn](images/openvpn.PNG)
![image_vpn](images/udp2rawopenvpn.PNG)
1. Bypasses UDP block/UDP QOS
2. No TCP over TCP problem (TCP over TCP problem http://sites.inka.de/bigred/devel/tcp-tcp.html ,https://community.openvpn.net/openvpn/ticket/2 )

View File

@@ -80,10 +80,7 @@ struct ip_port_t
char * to_s();
};
struct fd_info_t
{
ip_port_t ip_port;
};
typedef u64_t fd64_t;

View File

@@ -297,6 +297,7 @@ conv_manager_t::~conv_manager_t()
assert(oppsite_const_id==0);
}
}
assert(timer_fd64==0);
//if(oppsite_const_id!=0) //do this at conn_manager 's deconstuction function
//conn_manager.const_id_mp.erase(oppsite_const_id);
if(blob!=0)
@@ -388,6 +389,7 @@ conv_manager_t::~conv_manager_t()
fd_manager.fd64_close(erase_it->second->timer_fd64);
erase_it->second->timer_fd64=0;
//timer_fd_mp.erase(erase_it->second->timer_fd);
//close(erase_it->second->timer_fd);// close will auto delte it from epoll
delete(erase_it->second);
@@ -732,9 +734,9 @@ int recv_safer(conn_info_t &conn_info,char &type,char* &data,int &len)///safer t
void server_clear_function(u64_t u64)//used in conv_manager in server mode.for server we have to use one udp fd for one conv(udp connection),
//so we have to close the fd when conv expires
{
int fd=int(u64);
int ret;
assert(fd!=0);
//int fd=int(u64);
// int ret;
//assert(fd!=0);
/*
epoll_event ev;
@@ -747,16 +749,18 @@ void server_clear_function(u64_t u64)//used in conv_manager in server mode.for s
mylog(log_fatal,"fd:%d epoll delete failed!!!!\n",fd);
myexit(-1); //this shouldnt happen
}*/ //no need
ret= close(fd); //closed fd should be auto removed from epoll
/*ret= close(fd); //closed fd should be auto removed from epoll
if (ret!=0)
{
mylog(log_fatal,"close fd %d failed !!!!\n",fd);
myexit(-1); //this shouldnt happen
}
}*/
//mylog(log_fatal,"size:%d !!!!\n",conn_manager.udp_fd_mp.size());
assert(fd_manager.exist(u64));
fd_manager.fd64_close(u64);
fd64_t fd64=u64;
assert(fd_manager.exist(fd64));
fd_manager.fd64_close(fd64);
//assert(conn_manager.udp_fd_mp.find(fd)!=conn_manager.udp_fd_mp.end());
//conn_manager.udp_fd_mp.erase(fd);

View File

@@ -95,7 +95,7 @@ struct conn_info_t //stores info for a raw connection.for client ,there is o
uint8_t oppsite_roller;
u64_t last_oppsite_roller_time;
ip_port_t ip_port;
// ip_port_t ip_port;
/*
const uint32_t &ip=raw_info.recv_info.src_ip;

View File

@@ -4,15 +4,17 @@ udp2raw tunnel通过raw socket给UDP包加上TCP或ICMP header进而绕过
支持心跳保活、自动重连,重连后会恢复上次连接,在底层掉线的情况下可以保持上层不掉线。同时有加密、防重放攻击、信道复用的功能。
**欢迎任何形式的转载**
[English](/README.md)
[udp2raw+kcptun step_by_step教程](kcptun_step_by_step.md)
[udp2raw+finalspeed step_by_step教程](finalspeed_step_by_step.md)
如果你需要加速跨国网游、网页浏览解决方案在另一个repo
**提示:**
udp2raw不是加速器只是一个帮助你绕过UDP限制的工具。如果你需要UDP加速器请看UDPspeeder。
UDPspeeder的repo:
https://github.com/wangyu-/UDPspeeder
# 支持的平台

63
fd_manager.cpp Normal file
View File

@@ -0,0 +1,63 @@
/*
* fd_manager.cpp
*
* Created on: Sep 25, 2017
* Author: root
*/
#include "fd_manager.h"
int fd_manager_t::fd_exist(int fd)
{
return fd_to_fd64_mp.find(fd)!=fd_to_fd64_mp.end();
}
int fd_manager_t::exist(fd64_t fd64)
{
return fd64_to_fd_mp.find(fd64)!=fd64_to_fd_mp.end();
}
int fd_manager_t::to_fd(fd64_t fd64)
{
assert(exist(fd64));
return fd64_to_fd_mp[fd64];
}
void fd_manager_t::fd64_close(fd64_t fd64)
{
assert(exist(fd64));
int fd=fd64_to_fd_mp[fd64];
fd64_to_fd_mp.erase(fd64);
fd_to_fd64_mp.erase(fd);
if(exist_info(fd64))
{
fd_info_mp.erase(fd64);
}
assert(close(fd)==0);
}
void fd_manager_t::reserve(int n)
{
fd_to_fd64_mp.reserve(n);
fd64_to_fd_mp.reserve(n);
fd_info_mp.reserve(n);
}
u64_t fd_manager_t::create(int fd)
{
assert(!fd_exist(fd));
fd64_t fd64=counter++;
fd_to_fd64_mp[fd]=fd64;
fd64_to_fd_mp[fd64]=fd;
return fd64;
}
fd_manager_t::fd_manager_t()
{
counter=u32_t(-1);
counter+=100;
reserve(10007);
}
fd_info_t & fd_manager_t::get_info(fd64_t fd64)
{
assert(exist(fd64));
return fd_info_mp[fd64];
}
int fd_manager_t::exist_info(fd64_t fd64)
{
return fd_info_mp.find(fd64)!=fd_info_mp.end();
}

43
fd_manager.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* fd_manager.h
*
* Created on: Sep 25, 2017
* Author: root
*/
#ifndef FD_MANAGER_H_
#define FD_MANAGER_H_
#include "common.h"
//#include "packet.h"
#include "connection.h"
struct fd_info_t
{
//ip_port_t ip_port;
conn_info_t *p_conn_info;
};
struct fd_manager_t //conver fd to a uniq 64bit number,avoid fd value conflict caused by close and re-create
//this class is not strictly necessary,it just makes epoll fd handling easier
{
fd_info_t & get_info(fd64_t fd64);
int exist_info(fd64_t);
int exist(fd64_t fd64);
int to_fd(fd64_t);
void fd64_close(fd64_t fd64);
void reserve(int n);
u64_t create(int fd);
fd_manager_t();
private:
u64_t counter;
unordered_map<int,fd64_t> fd_to_fd64_mp;
unordered_map<fd64_t,int> fd64_to_fd_mp;
unordered_map<fd64_t,fd_info_t> fd_info_mp;
int fd_exist(int fd);
//void remove_fd(int fd);
//fd64_t fd_to_fd64(int fd);
};
extern fd_manager_t fd_manager;
#endif /* FD_MANAGER_H_ */

BIN
images/udp2rawopenvpn.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -27,8 +27,6 @@ int client_on_timer(conn_info_t &conn_info) //for client. called when a timer is
mylog(log_trace,"<client_on_timer,send_info.ts_ack= %u>\n",send_info.ts_ack);
if(conn_info.state.client_current_state==client_idle)
{
fail_time_counter++;
@@ -603,8 +601,8 @@ int server_on_raw_recv_multi() //called when server received an raw packet
conn_info_t &conn_info=conn_manager.find_insert(ip,port);
conn_info.raw_info=tmp_raw_info;
conn_info.ip_port.ip=ip;
conn_info.ip_port.port=port;
//conn_info.ip_port.ip=ip;
//conn_info.ip_port.port=port;
packet_info_t &send_info=conn_info.raw_info.send_info;
packet_info_t &recv_info=conn_info.raw_info.recv_info;
@@ -826,6 +824,7 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
struct epoll_event ev;
fd64_t new_udp_fd64 = fd_manager.create(new_udp_fd);
fd_manager.get_info(new_udp_fd64).p_conn_info=&conn_info;
mylog(log_trace, "[%s]u64: %lld\n",ip_port, new_udp_fd64);
ev.events = EPOLLIN;
@@ -842,7 +841,7 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
conn_info.blob->conv_manager.insert_conv(tmp_conv_id, new_udp_fd64);
fd_manager.get_info(new_udp_fd64).ip_port=conn_info.ip_port;
//assert(conn_manager.udp_fd_mp.find(new_udp_fd)==conn_manager.udp_fd_mp.end());
@@ -857,11 +856,11 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
}
u64_t u64 = conn_info.blob->conv_manager.find_u64_by_conv(tmp_conv_id);
fd64_t fd64 = conn_info.blob->conv_manager.find_u64_by_conv(tmp_conv_id);
conn_info.blob->conv_manager.update_active_time(tmp_conv_id);
int fd = int((u64 << 32u) >> 32u);
int fd = fd_manager.to_fd(fd64);
mylog(log_trace, "[%s]received a data from fake tcp,len:%d\n",ip_port, data_len);
int ret = send(fd, data + sizeof(u32_t),
@@ -925,10 +924,9 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info,char * ip_port,u32_t tmp
//g_conn_info=conn_info;
int new_timer_fd;
set_timer_server(epollfd, new_timer_fd);
conn_info.timer_fd64=fd_manager.create(new_timer_fd);
set_timer_server(epollfd, new_timer_fd,conn_info.timer_fd64);
fd_manager.get_info(conn_info.timer_fd64).ip_port=conn_info.ip_port;
fd_manager.get_info(conn_info.timer_fd64).p_conn_info=&conn_info;
//assert(conn_manager.timer_fd_mp.find(new_timer_fd)==conn_manager.timer_fd_mp.end());
//conn_manager.timer_fd_mp[new_timer_fd] = &conn_info;//pack_u64(ip,port);
@@ -1484,7 +1482,7 @@ int server_event_loop()
fd64_t fd64=events[idx].data.u64;
if(fd_manager.exist(fd64))
if(!fd_manager.exist(fd64))
{
mylog(log_trace ,"fd64 no longer exist\n");
continue;
@@ -1492,23 +1490,21 @@ int server_event_loop()
assert(fd_manager.exist_info(fd64));
ip_port_t ip_port=fd_manager.get_info(fd64).ip_port;
u32_t ip=ip_port.ip;
u32_t port=ip_port.port;
assert(conn_manager.exist(ip,port));
conn_info_t* p_conn_info=conn_manager.find_insert_p(ip,port);
conn_info_t* p_conn_info=fd_manager.get_info(fd64).p_conn_info;
u32_t ip=p_conn_info->raw_info.send_info.dst_ip;
u32_t port=p_conn_info->raw_info.send_info.dst_port;
//assert(conn_manager.exist(ip,port));
///conn_info_t* p_conn_info=conn_manager.find_insert_p(ip,port);
if(fd64==p_conn_info->timer_fd64)//////////timer_fd64
{
if(debug_flag)begin_time=get_current_time();
int fd=get_u64_l(events[idx].data.u64);
//int fd=get_u64_l(events[idx].data.u64);
int fd=fd_manager.to_fd(fd64);
u64_t dummy;
read(fd, &dummy, 8);

View File

@@ -15,7 +15,7 @@ SOURCES_AES_ACC=$(COMMON) $(wildcard lib/aes_acc/aes*.c)
NAME=udp2raw
TARGETS=amd64 arm amd64_hw_aes arm_asm_aes mips24kc_be mips24kc_be_asm_aes x86 x86_asm_aes mips24kc_le mips24kc_le_asm_aes
TAR=${NAME}_binaries.tar.gz `echo ${TARGETS}|sed -r 's/([^ ]+)/udp2raw_\1/g'`
TAR=${NAME}_binaries.tar.gz `echo ${TARGETS}|sed -r 's/([^ ]+)/udp2raw_\1/g'` version.txt
all:git_version
rm -f ${NAME}
@@ -69,6 +69,7 @@ cross3:git_version
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -O3
release: ${TARGETS}
cp git_version.h version.txt
tar -zcvf ${TAR}
clean:

View File

@@ -951,7 +951,7 @@ int set_timer(int epollfd,int &timer_fd)//put a timer_fd into epoll,general func
}
int set_timer_server(int epollfd,int &timer_fd)//only for server
int set_timer_server(int epollfd,int &timer_fd,fd64_t &fd64)//only for server
{
int ret;
epoll_event ev;
@@ -969,9 +969,11 @@ int set_timer_server(int epollfd,int &timer_fd)//only for server
its.it_value.tv_nsec=1; //imidiately
timerfd_settime(timer_fd,0,&its,0);
fd64=fd_manager.create(timer_fd);
ev.events = EPOLLIN;
ev.data.u64 = pack_u64(2,timer_fd);////difference
ev.data.u64 = fd64;////difference
ret=epoll_ctl(epollfd, EPOLL_CTL_ADD, timer_fd, &ev);
if (ret < 0) {

2
misc.h
View File

@@ -112,7 +112,7 @@ void iptables_rule();
void pre_process_arg(int argc, char *argv[]);//mainly for load conf file;
int unit_test();
int set_timer(int epollfd,int &timer_fd);
int set_timer_server(int epollfd,int &timer_fd);
int set_timer_server(int epollfd,int &timer_fd,fd64_t &fd64);
int handle_lower_level(raw_info_t &raw_info);
int add_iptables_rule(const char *);

View File

@@ -1820,17 +1820,17 @@ int get_src_adress(u32_t &ip,u32_t remote_ip_uint32,int remote_port) //a trick
return 0;
}
int try_to_list_and_bind(int bind_fd,u32_t local_ip_uint32,int port) //try to bind to a port,may fail.
int try_to_list_and_bind(int &fd,u32_t local_ip_uint32,int port) //try to bind to a port,may fail.
{
int old_bind_fd=bind_fd;
int old_bind_fd=fd;
if(raw_mode==mode_faketcp)
{
bind_fd=socket(AF_INET,SOCK_STREAM,0);
fd=socket(AF_INET,SOCK_STREAM,0);
}
else if(raw_mode==mode_udp||raw_mode==mode_icmp)
{
bind_fd=socket(AF_INET,SOCK_DGRAM,0);
fd=socket(AF_INET,SOCK_DGRAM,0);
}
if(old_bind_fd!=-1)
{
@@ -1844,7 +1844,7 @@ int try_to_list_and_bind(int bind_fd,u32_t local_ip_uint32,int port) //try to b
temp_bind_addr.sin_port = htons(port);
temp_bind_addr.sin_addr.s_addr = local_ip_uint32;
if (bind(bind_fd, (struct sockaddr*)&temp_bind_addr, sizeof(temp_bind_addr)) !=0)
if (bind(fd, (struct sockaddr*)&temp_bind_addr, sizeof(temp_bind_addr)) !=0)
{
mylog(log_debug,"bind fail\n");
return -1;
@@ -1852,19 +1852,19 @@ int try_to_list_and_bind(int bind_fd,u32_t local_ip_uint32,int port) //try to b
if(raw_mode==mode_faketcp)
{
if (listen(bind_fd, SOMAXCONN) != 0) {
if (listen(fd, SOMAXCONN) != 0) {
mylog(log_warn,"listen fail\n");
return -1;
}
}
return 0;
}
int client_bind_to_a_new_port(int bind_fd,u32_t local_ip_uint32)//find a free port and bind to it.
int client_bind_to_a_new_port(int &fd,u32_t local_ip_uint32)//find a free port and bind to it.
{
int raw_send_port=10000+get_true_random_number()%(65535-10000);
for(int i=0;i<1000;i++)//try 1000 times at max,this should be enough
{
if (try_to_list_and_bind(bind_fd,local_ip_uint32,raw_send_port)==0)
if (try_to_list_and_bind(fd,local_ip_uint32,raw_send_port)==0)
{
return raw_send_port;
}

View File

@@ -99,9 +99,9 @@ int find_lower_level_info(u32_t ip,u32_t &dest_ip,string &if_name,string &hw);
int get_src_adress(u32_t &ip,u32_t remote_ip_uint32,int remote_port); //a trick to get src adress for a dest adress,so that we can use the src address in raw socket as source ip
int try_to_list_and_bind(int bind_fd,u32_t local_ip_uint32,int port); //try to bind to a port,may fail.
int try_to_list_and_bind(int & bind_fd,u32_t local_ip_uint32,int port); //try to bind to a port,may fail.
int client_bind_to_a_new_port(int bind_fd,u32_t local_ip_uint32);//find a free port and bind to it.
int client_bind_to_a_new_port(int & bind_fd,u32_t local_ip_uint32);//find a free port and bind to it.
int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen);