Compare commits
39 Commits
20171024.0
...
20171123.1
Author | SHA1 | Date | |
---|---|---|---|
|
3bc07d5c86 | ||
|
f081ab751d | ||
|
91097eab5d | ||
|
c22b5e9680 | ||
|
9162a533d3 | ||
|
b01b087949 | ||
|
51b45c8f39 | ||
|
995ea8c98d | ||
|
aec81eb0c9 | ||
|
8b59b4afb9 | ||
|
c33bb552cd | ||
|
9516cfe99d | ||
|
5b1e59cae2 | ||
|
211d7ea4d3 | ||
|
7599d99fcc | ||
|
706cb0b583 | ||
|
43ae798e77 | ||
|
2f12d55229 | ||
|
0a4555dd42 | ||
|
14ece87bc3 | ||
|
50f682daf4 | ||
|
d487ca57f7 | ||
|
482e658858 | ||
|
069a9ba2b4 | ||
|
c591902be1 | ||
|
6a825dc51e | ||
|
1bdb6a5720 | ||
|
1afe8d7317 | ||
|
a54a0e269b | ||
|
e8398d0d31 | ||
|
dc43cb740b | ||
|
2e6be9e159 | ||
|
7a23486533 | ||
|
6515d428e9 | ||
|
c3e1dab838 | ||
|
00edb620be | ||
|
95ee6e64dc | ||
|
deeb7395a4 | ||
|
537f8a6311 |
6
ISSUE_TEMPLATE.md
Normal 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可能被忽略,或被直接关掉)
|
17
README.md
@@ -1,16 +1,21 @@
|
||||
# Udp2raw-tunnel
|
||||

|
||||
|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
[简体中文](/doc/README.zh-cn.md)
|
||||
|
||||
# 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
|
||||
@@ -191,6 +196,10 @@ Then start the server with
|
||||
./udp2raw_amd64 --conf-file server.conf
|
||||
```
|
||||
|
||||
### `--fifo`
|
||||
Use a fifo(named pipe) for sending commands to the running program. For example `--fifo fifo.file`.
|
||||
|
||||
At client side,you can use `echo reconnect >fifo.file` to force client to reconnect.Currently no command has been implemented for server.
|
||||
|
||||
# Peformance Test
|
||||
#### Test method:
|
||||
@@ -222,7 +231,7 @@ raw_mode: faketcp cipher_mode: aes128cbc auth_mode: md5
|
||||
|
||||
# Application
|
||||
## Tunneling any traffic via raw traffic by using udp2raw +openvpn
|
||||

|
||||

|
||||
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 )
|
||||
|
16
common.cpp
@@ -593,7 +593,21 @@ int create_fifo(char * file)
|
||||
return fifo_fd;
|
||||
}
|
||||
|
||||
|
||||
void ip_port_t::from_u64(u64_t u64)
|
||||
{
|
||||
ip=get_u64_h(u64);
|
||||
port=get_u64_l(u64);
|
||||
}
|
||||
u64_t ip_port_t::to_u64()
|
||||
{
|
||||
return pack_u64(ip,port);
|
||||
}
|
||||
char * ip_port_t::to_s()
|
||||
{
|
||||
static char res[40];
|
||||
sprintf(res,"%s:%d",my_ntoa(ip),port);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
15
common.h
@@ -70,6 +70,21 @@ typedef u64_t padding_t;
|
||||
|
||||
typedef u64_t anti_replay_seq_t;
|
||||
|
||||
|
||||
struct ip_port_t
|
||||
{
|
||||
u32_t ip;
|
||||
int port;
|
||||
void from_u64(u64_t u64);
|
||||
u64_t to_u64();
|
||||
char * to_s();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
typedef u64_t fd64_t;
|
||||
|
||||
const int max_data_len=1600;
|
||||
const int buf_len=max_data_len+400;
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "connection.h"
|
||||
#include "encrypt.h"
|
||||
#include "fd_manager.h"
|
||||
|
||||
|
||||
int disable_anti_replay=0;//if anti_replay windows is diabled
|
||||
@@ -249,7 +250,7 @@ conv_manager_t::~conv_manager_t()
|
||||
last_state_time=0;
|
||||
oppsite_const_id=0;
|
||||
|
||||
timer_fd=0;
|
||||
timer_fd64=0;
|
||||
|
||||
my_roller=0;
|
||||
oppsite_roller=0;
|
||||
@@ -296,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)
|
||||
@@ -310,9 +312,9 @@ conv_manager_t::~conv_manager_t()
|
||||
ready_num=0;
|
||||
mp.reserve(10007);
|
||||
clear_it=mp.begin();
|
||||
timer_fd_mp.reserve(10007);
|
||||
// timer_fd_mp.reserve(10007);
|
||||
const_id_mp.reserve(10007);
|
||||
udp_fd_mp.reserve(100007);
|
||||
// udp_fd_mp.reserve(100007);
|
||||
last_clear_time=0;
|
||||
//current_ready_ip=0;
|
||||
// current_ready_port=0;
|
||||
@@ -372,21 +374,33 @@ conv_manager_t::~conv_manager_t()
|
||||
ready_num--;
|
||||
assert(i32_t(ready_num)!=-1);
|
||||
assert(erase_it->second!=0);
|
||||
assert(erase_it->second->timer_fd !=0);
|
||||
|
||||
assert(erase_it->second->timer_fd64 !=0);
|
||||
|
||||
assert(fd_manager.exist(erase_it->second->timer_fd64));
|
||||
|
||||
assert(erase_it->second->oppsite_const_id!=0);
|
||||
assert(const_id_mp.find(erase_it->second->oppsite_const_id)!=const_id_mp.end());
|
||||
assert(timer_fd_mp.find(erase_it->second->timer_fd)!=timer_fd_mp.end());
|
||||
|
||||
|
||||
//assert(timer_fd_mp.find(erase_it->second->timer_fd)!=timer_fd_mp.end());
|
||||
|
||||
const_id_mp.erase(erase_it->second->oppsite_const_id);
|
||||
timer_fd_mp.erase(erase_it->second->timer_fd);
|
||||
close(erase_it->second->timer_fd);// close will auto delte it from epoll
|
||||
|
||||
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);
|
||||
mp.erase(erase_it->first);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(erase_it->second->blob==0);
|
||||
assert(erase_it->second->timer_fd ==0);
|
||||
assert(erase_it->second->timer_fd64 ==0);
|
||||
|
||||
|
||||
assert(erase_it->second->oppsite_const_id==0);
|
||||
delete(erase_it->second);
|
||||
mp.erase(erase_it->first);
|
||||
@@ -697,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;
|
||||
@@ -720,9 +744,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;
|
||||
|
||||
@@ -735,14 +759,19 @@ 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(conn_manager.udp_fd_mp.find(fd)!=conn_manager.udp_fd_mp.end());
|
||||
conn_manager.udp_fd_mp.erase(fd);
|
||||
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);
|
||||
}
|
||||
|
@@ -85,7 +85,8 @@ struct conn_info_t //stores info for a raw connection.for client ,there is o
|
||||
id_t oppsite_id;
|
||||
|
||||
|
||||
int timer_fd;
|
||||
fd64_t timer_fd64;
|
||||
|
||||
id_t oppsite_const_id;
|
||||
|
||||
blob_t *blob;
|
||||
@@ -94,6 +95,8 @@ 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;
|
||||
|
||||
/*
|
||||
const uint32_t &ip=raw_info.recv_info.src_ip;
|
||||
const uint16_t &port=raw_info.recv_info.src_port;
|
||||
@@ -113,8 +116,8 @@ struct conn_manager_t //manager for connections. for client,we dont need conn_m
|
||||
|
||||
u32_t ready_num;
|
||||
|
||||
unordered_map<int,conn_info_t *> udp_fd_mp; //a bit dirty to used pointer,but can void unordered_map search
|
||||
unordered_map<int,conn_info_t *> timer_fd_mp;//we can use pointer here since unordered_map.rehash() uses shallow copy
|
||||
//unordered_map<int,conn_info_t *> udp_fd_mp; //a bit dirty to used pointer,but can void unordered_map search
|
||||
//unordered_map<int,conn_info_t *> timer_fd_mp;//we can use pointer here since unordered_map.rehash() uses shallow copy
|
||||
|
||||
unordered_map<id_t,conn_info_t *> const_id_mp;
|
||||
|
||||
|
@@ -1,25 +1,36 @@
|
||||
Udp2raw-tunnel
|
||||

|
||||
# Udp2raw-tunnel
|
||||

|
||||
udp2raw tunnel,通过raw socket给UDP包加上TCP或ICMP header,进而绕过UDP屏蔽或QoS,或在UDP不稳定的环境下提升稳定性。可以有效防止在使用kcptun或者finalspeed的情况下udp端口被运营商限速。
|
||||
|
||||
支持心跳保活、自动重连,重连后会恢复上次连接,在底层掉线的情况下可以保持上层不掉线。同时有加密、防重放攻击、信道复用的功能。
|
||||
|
||||
**欢迎任何形式的转载**
|
||||
|
||||
[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
|
||||
# 支持的平台
|
||||
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
|
||||
@@ -49,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
|
||||
@@ -98,7 +109,7 @@ udp2raw可以用非root账号运行,这样更安全。具体方法见:[#26](
|
||||
### 命令选项
|
||||
```
|
||||
udp2raw-tunnel
|
||||
git version:adbe7d110f build date:Sep 6 2017 05:37:45
|
||||
git version:6e1df4b39f build date:Oct 24 2017 09:21:15
|
||||
repository: https://github.com/wangyu-/udp2raw-tunnel
|
||||
|
||||
usage:
|
||||
@@ -121,7 +132,9 @@ client options:
|
||||
other options:
|
||||
--conf-file <string> read options from a configuration file instead of command line.
|
||||
check example.conf in repo for format
|
||||
--log-level <number> 0:never 1:fatal 2:error 3:warn
|
||||
--fifo <string> use a fifo(named pipe) for sending commands to the running program,
|
||||
check readme.md in repository for supported commands.
|
||||
--log-level <number> 0:never 1:fatal 2:error 3:warn
|
||||
4:info (default) 5:debug 6:trace
|
||||
--log-position enable file name,function name,line number in log
|
||||
--disable-color disable log color
|
||||
@@ -135,7 +148,7 @@ other options:
|
||||
2:increase seq randomly, about every 3 packets,simply ack last seq
|
||||
3:simulate an almost real seq/ack procedure(default)
|
||||
4:similiar to 3,but do not consider TCP Option Window_Scale,
|
||||
maybe useful when firewall doesnt support TCP Option
|
||||
maybe useful when firewall doesnt support TCP Option
|
||||
--lower-level <string> send packets at OSI level 2, format:'if_name#dest_mac_adress'
|
||||
ie:'eth0#00:23:45:67:89:b9'.or try '--lower-level auto' to obtain
|
||||
the parameter automatically,specify it manually if 'auto' failed
|
||||
@@ -159,6 +172,11 @@ facktcp模式并没有模拟tcp的全部。所以理论上有办法把faketcp和
|
||||
### `--keep-rule`
|
||||
定期主动检查iptables,如果udp2raw添加的iptables规则丢了,就重新添加。在一些iptables可能会被其他程序清空的情况下(比如梅林固件和openwrt的路由器)格外有用。
|
||||
|
||||
### `--fifo`
|
||||
指定一个fifo(named pipe)来向运行中的程序发送命令,例如`--fifo fifo.file`:
|
||||
|
||||
在client端,可以用`echo reconnect >fifo.file`来强制client换端口重连(上层不断线).对Server,目前没有效果。
|
||||
|
||||
### `--lower-level`
|
||||
大部分udp2raw不能连通的情况都是设置了不兼容的iptables造成的。--lower-level选项允许绕过本地iptables。在一些iptables不好改动的情况下尤其有效(比如你用的是梅林固件,iptables全是固件自己生成的)。
|
||||
|
||||
|
63
fd_manager.cpp
Normal 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
@@ -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
After Width: | Height: | Size: 58 KiB |
1
images/wiki/111
Normal file
@@ -0,0 +1 @@
|
||||
|
BIN
images/wiki/mac_nat_vb1.PNG
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
images/wiki/mac_nat_vb2.PNG
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
images/wiki/mac_nat_vb3.PNG
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
images/wiki/mac_nat_vb4.PNG
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
images/wiki/windows_nat.PNG
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
images/wiki/windows_nat_vb1.PNG
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
images/wiki/windows_nat_vb2.PNG
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
images/wiki/windows_nat_vm1.PNG
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
images/wiki/windows_nat_vm2.PNG
Normal file
After Width: | Height: | Size: 29 KiB |
198
main.cpp
@@ -5,8 +5,11 @@
|
||||
#include "log.h"
|
||||
#include "lib/md5.h"
|
||||
#include "encrypt.h"
|
||||
#include "fd_manager.h"
|
||||
|
||||
|
||||
char hb_buf[buf_len];
|
||||
|
||||
int mtu_warn=1375;//if a packet larger than mtu warn is receviced,there will be a warning
|
||||
|
||||
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);
|
||||
@@ -26,8 +29,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++;
|
||||
@@ -226,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;
|
||||
@@ -238,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;
|
||||
}
|
||||
@@ -283,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);
|
||||
@@ -430,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;
|
||||
}
|
||||
@@ -440,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;
|
||||
@@ -602,6 +611,9 @@ 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;
|
||||
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
raw_info_t &raw_info=conn_info.raw_info;
|
||||
@@ -771,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();
|
||||
@@ -785,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)) {
|
||||
@@ -821,11 +834,13 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
|
||||
}
|
||||
struct epoll_event ev;
|
||||
|
||||
u64_t u64 = (u32_t(new_udp_fd))+(1llu<<32u);
|
||||
mylog(log_trace, "[%s]u64: %lld\n",ip_port, u64);
|
||||
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;
|
||||
|
||||
ev.data.u64 = u64;
|
||||
ev.data.u64 = new_udp_fd64;
|
||||
|
||||
ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, new_udp_fd, &ev);
|
||||
|
||||
@@ -835,10 +850,13 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
|
||||
return -1;
|
||||
}
|
||||
|
||||
conn_info.blob->conv_manager.insert_conv(tmp_conv_id, new_udp_fd);
|
||||
assert(conn_manager.udp_fd_mp.find(new_udp_fd)==conn_manager.udp_fd_mp.end());
|
||||
conn_info.blob->conv_manager.insert_conv(tmp_conv_id, new_udp_fd64);
|
||||
|
||||
conn_manager.udp_fd_mp[new_udp_fd] = &conn_info;
|
||||
|
||||
|
||||
//assert(conn_manager.udp_fd_mp.find(new_udp_fd)==conn_manager.udp_fd_mp.end());
|
||||
|
||||
//conn_manager.udp_fd_mp[new_udp_fd] = &conn_info;
|
||||
|
||||
//pack_u64(conn_info.raw_info.recv_info.src_ip,conn_info.raw_info.recv_info.src_port);
|
||||
|
||||
@@ -849,11 +867,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),
|
||||
@@ -906,21 +924,25 @@ 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();
|
||||
|
||||
//g_conn_info=conn_info;
|
||||
int new_timer_fd;
|
||||
set_timer_server(epollfd, new_timer_fd);
|
||||
conn_info.timer_fd=new_timer_fd;
|
||||
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);
|
||||
set_timer_server(epollfd, new_timer_fd,conn_info.timer_fd64);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
//timer_fd_mp[new_timer_fd]
|
||||
@@ -969,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();
|
||||
|
||||
|
||||
|
||||
@@ -1168,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);
|
||||
}
|
||||
}
|
||||
@@ -1196,7 +1224,12 @@ int client_event_loop()
|
||||
else if (events[idx].data.u64 == (u64_t)fifo_fd)
|
||||
{
|
||||
int len=read (fifo_fd, buf, sizeof (buf));
|
||||
assert(len>=0);
|
||||
//assert(len>=0);
|
||||
if(len<0)
|
||||
{
|
||||
mylog(log_warn,"fifo read failed len=%d,errno=%s\n",len,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
buf[len]=0;
|
||||
while(len>=1&&buf[len-1]=='\n')
|
||||
buf[len-1]=0;
|
||||
@@ -1407,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);
|
||||
}
|
||||
}
|
||||
@@ -1452,29 +1485,58 @@ int server_event_loop()
|
||||
else if (events[idx].data.u64 == (u64_t)fifo_fd)
|
||||
{
|
||||
int len=read (fifo_fd, buf, sizeof (buf));
|
||||
assert(len>=0);
|
||||
if(len<0)
|
||||
{
|
||||
mylog(log_warn,"fifo read failed len=%d,errno=%s\n",len,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
//assert(len>=0);
|
||||
buf[len]=0;
|
||||
while(len>=1&&buf[len-1]=='\n')
|
||||
buf[len-1]=0;
|
||||
mylog(log_info,"got data from fifo,len=%d,s=[%s]\n",len,buf);
|
||||
mylog(log_info,"unknown command\n");
|
||||
}
|
||||
else if ((events[idx].data.u64 >>32u) == 2u)
|
||||
else if (events[idx].data.u64>u32_t(-1) )
|
||||
{
|
||||
|
||||
fd64_t fd64=events[idx].data.u64;
|
||||
|
||||
if(!fd_manager.exist(fd64))
|
||||
{
|
||||
mylog(log_trace ,"fd64 no longer exist\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(fd_manager.exist_info(fd64));
|
||||
|
||||
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);
|
||||
|
||||
if(conn_manager.timer_fd_mp.find(fd)==conn_manager.timer_fd_mp.end()) //this can happen,when fd is a just closed fd
|
||||
/*if(conn_manager.timer_fd_mp.find(fd)==conn_manager.timer_fd_mp.end()) //this can happen,when fd is a just closed fd
|
||||
{
|
||||
mylog(log_info,"timer_fd no longer exits\n");
|
||||
continue;
|
||||
}
|
||||
conn_info_t* p_conn_info=conn_manager.timer_fd_mp[fd];
|
||||
u32_t ip=p_conn_info->raw_info.recv_info.src_ip;
|
||||
u32_t port=p_conn_info->raw_info.recv_info.src_port;
|
||||
assert(conn_manager.exist(ip,port));//TODO remove this for peformance
|
||||
}*/
|
||||
//conn_info_t* p_conn_info=conn_manager.timer_fd_mp[fd];
|
||||
//u32_t ip=p_conn_info->raw_info.recv_info.src_ip;
|
||||
//u32_t port=p_conn_info->raw_info.recv_info.src_port;
|
||||
//assert(conn_manager.exist(ip,port));//TODO remove this for peformance
|
||||
|
||||
assert(p_conn_info->state.server_current_state == server_ready); //TODO remove this for peformance
|
||||
|
||||
@@ -1490,30 +1552,36 @@ int server_event_loop()
|
||||
end_time=get_current_time();
|
||||
mylog(log_debug,"(events[idx].data.u64 >>32u) == 2u ,%llu,%llu,%llu \n",begin_time,end_time,end_time-begin_time);
|
||||
}
|
||||
}
|
||||
else if ((events[idx].data.u64 >>32u) == 1u)
|
||||
{
|
||||
|
||||
}
|
||||
else//udp_fd64
|
||||
{
|
||||
//}
|
||||
//else if ((events[idx].data.u64 >>32u) == 1u)
|
||||
//{
|
||||
//uint32_t conv_id=events[n].data.u64>>32u;
|
||||
|
||||
if(debug_flag)begin_time=get_current_time();
|
||||
|
||||
int fd=int((events[idx].data.u64<<32u)>>32u);
|
||||
//int fd=int((events[idx].data.u64<<32u)>>32u);
|
||||
|
||||
/*
|
||||
if(conn_manager.udp_fd_mp.find(fd)==conn_manager.udp_fd_mp.end()) //this can happen,when fd is a just closed fd
|
||||
{
|
||||
mylog(log_debug,"fd no longer exists in udp_fd_mp,udp fd %d\n",fd);
|
||||
recv(fd,0,0,0);
|
||||
continue;
|
||||
}
|
||||
conn_info_t* p_conn_info=conn_manager.udp_fd_mp[fd];
|
||||
}*/
|
||||
//conn_info_t* p_conn_info=conn_manager.udp_fd_mp[fd];
|
||||
|
||||
u32_t ip=p_conn_info->raw_info.recv_info.src_ip;
|
||||
u32_t port=p_conn_info->raw_info.recv_info.src_port;
|
||||
if(!conn_manager.exist(ip,port))//TODO remove this for peformance
|
||||
//u32_t ip=p_conn_info->raw_info.recv_info.src_ip;
|
||||
//u32_t port=p_conn_info->raw_info.recv_info.src_port;
|
||||
|
||||
/*if(!conn_manager.exist(ip,port))//TODO remove this for peformance
|
||||
{
|
||||
mylog(log_fatal,"ip port no longer exits 2!!!this shouldnt happen\n");
|
||||
myexit(-1);
|
||||
}
|
||||
}*/
|
||||
|
||||
if(p_conn_info->state.server_current_state!=server_ready)//TODO remove this for peformance
|
||||
{
|
||||
@@ -1523,14 +1591,11 @@ int server_event_loop()
|
||||
|
||||
conn_info_t &conn_info=*p_conn_info;
|
||||
|
||||
if(!conn_info.blob->conv_manager.is_u64_used(fd))
|
||||
{
|
||||
mylog(log_debug,"conv no longer exists,udp fd %d\n",fd);
|
||||
int recv_len=recv(fd,0,0,0); ///////////TODO ,delete this
|
||||
continue;
|
||||
}
|
||||
assert(conn_info.blob->conv_manager.is_u64_used(fd64));
|
||||
|
||||
u32_t conv_id=conn_info.blob->conv_manager.find_conv_by_u64(fd);
|
||||
u32_t conv_id=conn_info.blob->conv_manager.find_conv_by_u64(fd64);
|
||||
|
||||
int fd=fd_manager.to_fd(fd64);
|
||||
|
||||
int recv_len=recv(fd,buf,max_data_len,0);
|
||||
|
||||
@@ -1562,6 +1627,9 @@ int server_event_loop()
|
||||
end_time=get_current_time();
|
||||
mylog(log_debug,"(events[idx].data.u64 >>32u) == 1u,%lld,%lld,%lld \n",begin_time,end_time,end_time-begin_time);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
5
makefile
@@ -8,14 +8,14 @@ cc_arm= /toolchains/arm-2014.05/bin/arm-none-linux-gnueabi-g++
|
||||
#cc_bcm2708=/home/wangyu/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++
|
||||
FLAGS= -std=c++11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers
|
||||
|
||||
COMMON=main.cpp lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp connection.cpp misc.cpp -lpthread
|
||||
COMMON=main.cpp lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp connection.cpp misc.cpp fd_manager.cpp -lpthread
|
||||
SOURCES= $(COMMON) lib/aes_faster_c/aes.c lib/aes_faster_c/wrapper.c
|
||||
SOURCES_TINY_AES= $(COMMON) lib/aes.c
|
||||
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:
|
||||
|
39
misc.cpp
@@ -10,8 +10,17 @@
|
||||
#include "misc.h"
|
||||
#include "network.h"
|
||||
#include "connection.h"
|
||||
#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
|
||||
u32_t local_ip_uint32,remote_ip_uint32,source_ip_uint32;//convert from last line.
|
||||
int local_port = -1, remote_port=-1,source_port=0;//similiar to local_ip remote_ip,buf for port.source_port=0 indicates --source-port is not enabled
|
||||
@@ -146,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");
|
||||
|
||||
@@ -244,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}
|
||||
};
|
||||
|
||||
@@ -586,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);
|
||||
@@ -948,7 +979,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;
|
||||
@@ -966,9 +997,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) {
|
||||
|
18
misc.h
@@ -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.
|
||||
@@ -112,7 +114,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 *);
|
||||
|
16
network.cpp
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|