mirror of
https://github.com/wangyu-/udp2raw.git
synced 2025-09-16 04:04:27 +08:00
Compare commits
73 Commits
20170813.0
...
20170818.0
Author | SHA1 | Date | |
---|---|---|---|
|
eea016cab4 | ||
|
8356b45c3b | ||
|
e502076394 | ||
|
1ca79a07b6 | ||
|
b35d8ecd34 | ||
|
5ed3bae33d | ||
|
ec298b355e | ||
|
33fb57d6d0 | ||
|
bdc7e3e43f | ||
|
b10d9421d3 | ||
|
bdc1f74f8f | ||
|
5cca489825 | ||
|
3897ac3847 | ||
|
231fd05680 | ||
|
3a362f6598 | ||
|
99b3ddf6a1 | ||
|
09b00ef07b | ||
|
c0628959d4 | ||
|
9aa229569d | ||
|
842766ae76 | ||
|
9e5b2140b3 | ||
|
ac02ea91d7 | ||
|
837de123b2 | ||
|
358c5c47ff | ||
|
19102700a5 | ||
|
f848839232 | ||
|
a13269a0b0 | ||
|
1d8223632b | ||
|
e459b74bdf | ||
|
9429a1c7db | ||
|
f5d93cb80d | ||
|
f591ba101c | ||
|
5236bc2f4e | ||
|
c7d9312cd2 | ||
|
85dfdd416f | ||
|
7a62918b74 | ||
|
138b34335c | ||
|
c5c74a3f35 | ||
|
0a4f53e579 | ||
|
dc41a3dbad | ||
|
bd08278f1b | ||
|
bcab893c53 | ||
|
f3f43b85d2 | ||
|
ed354347fd | ||
|
fb32c56fb2 | ||
|
fb5546f83b | ||
|
bb67509179 | ||
|
4bc4d618db | ||
|
9f4c452cf6 | ||
|
455dcc1e84 | ||
|
cee22ec3dc | ||
|
0612b73e7e | ||
|
84697a35c9 | ||
|
78bf036e04 | ||
|
3ee73b048e | ||
|
8220cf30fb | ||
|
a061af0b89 | ||
|
746cda08d2 | ||
|
06f5541b2a | ||
|
97b73b06c9 | ||
|
f7319680d9 | ||
|
6dd52326b4 | ||
|
1ebef723bf | ||
|
744bf2dece | ||
|
7538204bd1 | ||
|
ae6dd0b196 | ||
|
fc515c770f | ||
|
491c322148 | ||
|
80f1070546 | ||
|
5a4e3302e2 | ||
|
e76ad81a04 | ||
|
7ac0d3561d | ||
|
32166d65ae |
48
README.md
48
README.md
@@ -1,9 +1,15 @@
|
||||
# Udp2raw-tunnel
|
||||

|
||||
|
||||
An Encrpyted,Anti-Replay,Multiplexed UDP Tunnel which can help you Bypass UDP Block or QoS by tunneling UDP traffic through Fake-TCP or ICMP by using raw socket.It aslo acts as a Connection Stablizer.
|
||||
A UDP Tunnel which tunnels UDP via FakeTCP/UDP/ICMP Traffic by using Raw Socket,helps you Bypass UDP FireWalls(or Unstable UDP Environment).Its Encrpyted,Anti-Replay and Multiplexed.It aslo acts as a Connection Stablizer.
|
||||
|
||||
[简体中文](/doc/README.zh-cn.md)
|
||||
# Support Platforms
|
||||
A Linux host (including desktop Linux,Android phone/tablet,OpenWRT router,or Raspberry PI) with root access.
|
||||
|
||||
For Winodws/MacOS,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).
|
||||
|
||||
|
||||
# Features
|
||||
### Send / Receive UDP Packet with fake-tcp/icmp headers
|
||||
Fake-tcp/icmp headers help you bypass UDP blocking, UDP QOS or improper UDP NAT behavior on some ISPs. Raw packets with UDP headers are also supported.In UDP header mode,it behaves just like a normal UDP tunnel,and you can just make use of the other features.
|
||||
@@ -11,11 +17,11 @@ Fake-tcp/icmp headers help you bypass UDP blocking, UDP QOS or improper UDP NAT
|
||||
### Simulate TCP Handshake
|
||||
Simulates the 3-way handshake, along with seq and ack_seq. TCP options MSS, sackOk, TS, TS_ack, wscale are also simulated. Real-time delivery guaranteed, no TCP over TCP problem when using OpenVPN.
|
||||
|
||||
### Encrpytion, Anti-Replay, Anti-MITM
|
||||
### Encrpytion, Anti-Replay, No MITM
|
||||
* Encrypt your traffic with AES-128-CBC.
|
||||
* Protect data integrity by MD5 or CRC32.
|
||||
* Defense replay attack with an anti-replay window, smiliar to IPSec and OpenVPN.
|
||||
* Authenticate mutually, no more MITM attacks.
|
||||
* Authenticate mutually, no MITM attacks.
|
||||
|
||||
### Failure Dectection & Stablization (Connection Recovery)
|
||||
Conection failures are detected by heartbeats. If timed-out,client will automatically change port number and reconnect. If reconnection is successful, the previous connection will be recovered, and all existing UDP conversations will stay vaild.
|
||||
@@ -34,21 +40,9 @@ For example, if you use UDP2RAW + OpenVPN, OpenVPN won't lose connection after a
|
||||
* **OpenWRT Support** No dependencies, easy to build. Binary for ar71xx are included in release.
|
||||
|
||||
### Keywords
|
||||
* UDP QoS Bypass
|
||||
* UDP Blocking Bypass
|
||||
* OpenVPN TCP over TCP problem
|
||||
* OpenVPN over ICMP
|
||||
* UDP to ICMP tunnel
|
||||
* UDP to TCP tunnel
|
||||
* UDP over ICMP
|
||||
* UDP over TCP
|
||||
`UDP QoS Bypass` `UDP Blocking Bypass` `OpenVPN TCP over TCP problem` `OpenVPN over ICMP` `UDP to ICMP tunnel` `UDP to TCP tunnel` `UDP over ICMP` `UDP over TCP`
|
||||
|
||||
# Getting Started
|
||||
### Prerequisites
|
||||
A Linux host (including desktop Linux, OpenWRT router, or Raspberry PI) with root access.
|
||||
|
||||
If you want to use it on MICRO$OFT Windows, you can use VMware or Hyper-V (both bridged mode and <del>NAT mode</del> are supported).
|
||||
|
||||
### Installing
|
||||
Download binary release from https://github.com/wangyu-/udp2raw-tunnel/releases
|
||||
|
||||
@@ -56,15 +50,22 @@ Download binary release from https://github.com/wangyu-/udp2raw-tunnel/releases
|
||||
Assume your UDP is blocked or being QOS-ed or just poorly supported. Assume your server ip is 44.55.66.77, you have a service listening on udp port 7777.
|
||||
|
||||
```bash
|
||||
# Run at client side
|
||||
./udp2raw_amd64 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -a -k "passwd" --raw-mode faketcp
|
||||
|
||||
# Run at server side:
|
||||
./udp2raw_amd64 -s -l0.0.0.0:4096 -r 127.0.0.1:7777 -a -k "passwd" --raw-mode faketcp
|
||||
|
||||
# Run at client side
|
||||
./udp2raw_amd64 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -a -k "passwd" --raw-mode faketcp
|
||||
```
|
||||
###### Server Output:
|
||||

|
||||
###### Client Output:
|
||||

|
||||
|
||||
Now,an encrypted raw tunnel has been established between client and server through TCP port 4096. Connecting to UDP port 3333 at the client side is equivalent to connecting to port 7777 at the server side. No UDP traffic will be exposed.
|
||||
|
||||
### Note
|
||||
to run on Android, see [Android_Guide](/doc/android_guide.md)
|
||||
|
||||
# Advanced Topic
|
||||
### Usage
|
||||
```
|
||||
@@ -185,3 +186,12 @@ https://github.com/ccsexyz/kcpraw
|
||||
Transparently tunnel your IP traffic through ICMP echo and reply packets.
|
||||
|
||||
https://github.com/DhavalKapil/icmptunnel
|
||||
|
||||
### Tcp Minion
|
||||
Tcp Minion is a project which modifid the code of tcp stack in kernel,and implemented real-time out-order udp packet delivery through this modified tcp stack.I failed to find the implementation,but there are some papers avaliable:
|
||||
|
||||
https://arxiv.org/abs/1103.0463
|
||||
|
||||
http://korz.cs.yale.edu/2009/tng/papers/pfldnet10.pdf
|
||||
|
||||
https://pdfs.semanticscholar.org/9e6f/e2306f4385b4eb5416d1fcab16e9361d6ba3.pdf
|
||||
|
110
common.cpp
110
common.cpp
@@ -55,13 +55,15 @@ int add_iptables_rule(char * s)
|
||||
strcpy(iptables_rule,s);
|
||||
char buf[300]="iptables -I ";
|
||||
strcat(buf,s);
|
||||
if(system(buf)==0)
|
||||
char *output;
|
||||
if(run_command(buf,output)==0)
|
||||
{
|
||||
mylog(log_warn,"auto added iptables rule by: %s\n",buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_fatal,"auto added iptables failed by: %s\n",buf);
|
||||
//mylog(log_fatal,"reason : %s\n",strerror(errno));
|
||||
myexit(-1);
|
||||
}
|
||||
return 0;
|
||||
@@ -73,13 +75,15 @@ int clear_iptables_rule()
|
||||
{
|
||||
char buf[300]="iptables -D ";
|
||||
strcat(buf,iptables_rule);
|
||||
if(system(buf)==0)
|
||||
char *output;
|
||||
if(run_command(buf,output)==0)
|
||||
{
|
||||
mylog(log_warn,"iptables rule cleared by: %s \n",buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
mylog(log_error,"clear iptables failed by: %s\n",buf);
|
||||
//mylog(log_error,"reason : %s\n",strerror(errno));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -135,7 +139,7 @@ u64_t ntoh64(u64_t a)
|
||||
{
|
||||
if(__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||
{
|
||||
return __bswap_64( a);
|
||||
return bswap_64( a);
|
||||
}
|
||||
else return a;
|
||||
|
||||
@@ -144,7 +148,7 @@ u64_t hton64(u64_t a)
|
||||
{
|
||||
if(__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||
{
|
||||
return __bswap_64( a);
|
||||
return bswap_64( a);
|
||||
}
|
||||
else return a;
|
||||
|
||||
@@ -310,3 +314,101 @@ bool larger_than_u16(uint16_t a,uint16_t b)
|
||||
}
|
||||
}
|
||||
}
|
||||
vector<string> string_to_vec(const char * s,const char * sp) {
|
||||
vector<string> res;
|
||||
string str=s;
|
||||
char *p = strtok ((char *)str.c_str(),sp);
|
||||
while (p != NULL)
|
||||
{
|
||||
res.push_back(p);
|
||||
//printf ("%s\n",p);
|
||||
p = strtok (NULL, sp);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
vector< vector <string> > string_to_vec2(const char * s)
|
||||
{
|
||||
vector< vector <string> > res;
|
||||
vector<string> lines=string_to_vec(s,"\n");
|
||||
for(int i=0;i<int(lines.size());i++)
|
||||
{
|
||||
vector<string> tmp;
|
||||
tmp=string_to_vec(lines[i].c_str(),"\t ");
|
||||
res.push_back(tmp);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
int read_file(const char * file,char * &output)
|
||||
{
|
||||
static char buf[1024*1024+100];
|
||||
buf[sizeof(buf)-1]=0;
|
||||
int fd=open(file,O_RDONLY);
|
||||
if(fd==-1)
|
||||
{
|
||||
mylog(log_error,"read_file %s fail\n",file);
|
||||
return -1;
|
||||
}
|
||||
int len=read(fd,buf,1024*1024);
|
||||
if(len==1024*1024)
|
||||
{
|
||||
buf[0]=0;
|
||||
mylog(log_error,"too long,buf not larger enough\n");
|
||||
return -2;
|
||||
}
|
||||
else if(len<0)
|
||||
{
|
||||
buf[0]=0;
|
||||
mylog(log_error,"read fail %d\n");
|
||||
return -3;
|
||||
}
|
||||
else
|
||||
{
|
||||
output=buf;
|
||||
buf[len]=0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int run_command(const char * command,char * &output) {
|
||||
FILE *in;
|
||||
mylog(log_debug,"run_command %s\n",command);
|
||||
static char buf[1024*1024+100];
|
||||
buf[sizeof(buf)-1]=0;
|
||||
if(!(in = popen(command, "r"))){
|
||||
mylog(log_error,"command %s popen failed,errno %s\n",command,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int len =fread(buf, 1024*1024, 1, in);
|
||||
if(len==1024*1024)
|
||||
{
|
||||
buf[0]=0;
|
||||
mylog(log_error,"too long,buf not larger enough\n");
|
||||
return -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[len]=0;
|
||||
}
|
||||
int ret;
|
||||
if(( ret=ferror(in) ))
|
||||
{
|
||||
mylog(log_error,"command %s fread failed,ferror return value %d \n",command,ret);
|
||||
return -2;
|
||||
}
|
||||
//if(output!=0)
|
||||
output=buf;
|
||||
ret= pclose(in);
|
||||
|
||||
int ret2=WEXITSTATUS(ret);
|
||||
|
||||
if(ret!=0||ret2!=0)
|
||||
{
|
||||
mylog(log_error,"commnad %s ,pclose returned %d ,WEXITSTATUS %d,errnor :%s \n",command,ret,ret2,strerror(errno));
|
||||
return -3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
11
common.h
11
common.h
@@ -43,11 +43,12 @@
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <linux/if_packet.h>
|
||||
|
||||
|
||||
#include <byteswap.h>
|
||||
|
||||
|
||||
#include<unordered_map>
|
||||
#include<vector>
|
||||
#include<string>
|
||||
using namespace std;
|
||||
|
||||
|
||||
@@ -144,4 +145,10 @@ int add_iptables_rule(char *);
|
||||
|
||||
int clear_iptables_rule();
|
||||
|
||||
int run_command(const char * command,char * &output);
|
||||
int read_file(const char * file,char * &output);
|
||||
|
||||
vector<string> string_to_vec(const char * s,const char * sp);
|
||||
vector< vector <string> > string_to_vec2(const char * s);
|
||||
|
||||
#endif /* COMMON_H_ */
|
||||
|
@@ -1,6 +1,10 @@
|
||||
Udp2raw-tunnel
|
||||

|
||||
加密、防重放攻击的、信道复用的udp tunnel,利用raw socket中转udp流量.同时有心跳保活,且在断线重连后保持上层连接不掉线的功能。
|
||||
udp2raw tunnel,通过raw socket给UDP包加上TCP或ICMP header,进而绕过UDP屏蔽或QoS,或在UDP不稳定的环境下提升稳定性。可以有效防止在使用kcptun或者finalspeed的情况下udp端口被运营商限速。
|
||||
|
||||
支持心跳保活、自动重连,重连后会恢复上次连接,在底层掉线的情况下可以保持上层不掉线。同时有加密、防重放攻击、信道复用的功能。
|
||||
|
||||
**欢迎任何形式的转载**
|
||||
|
||||
[English](/README.md)
|
||||
|
||||
@@ -11,6 +15,12 @@ Udp2raw-tunnel
|
||||
如果你需要加速跨国网游、网页浏览,解决方案在另一个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,很容易安装)。
|
||||
|
||||
# 功能特性
|
||||
### 把udp流量伪装成tcp /icmp
|
||||
用raw socket给udp包加上tcp/icmp包头,可以突破udp流量限制或Udp QOS。或者在udp nat有问题的环境下,提升稳定性。 另外也支持用raw 发udp包,这样流量不会被伪装,只会被加密。
|
||||
@@ -26,7 +36,7 @@ Client能用单倍的超时时间检测到单向链路的失效,不管是上
|
||||
对于有大量client的情况,对于不同client,server发送的心跳是错开时间发送的,不会因为短时间发送大量的心跳而造成拥塞和延迟抖动。
|
||||
|
||||
### 加密 防重放攻击 防中间人攻击
|
||||
用aes128cbc加密,md5/crc32做数据完整校验。用类似ipsec/openvpn的 replay windows机制来防止重放攻击。
|
||||
用aes128cbc加密,md5/crc32做数据完整校验。用类似ipsec/openvpn的 replay window机制来防止重放攻击。
|
||||
|
||||
设计目标是,即使攻击者可以监听到tunnel的所有包,可以选择性丢弃tunnel的任意包,可以重放任意包;攻击者也没办法获得tunnel承载的任何数据,也没办法向tunnel的数据流中通过包构造/包重放插入任何数据。client和server互相认证对方,无法被中间人攻击。
|
||||
|
||||
@@ -48,9 +58,6 @@ epoll纯异步,高并发,除了回收过期连接外,所有操作的时间
|
||||
|
||||
# 简明操作说明
|
||||
|
||||
### 环境要求
|
||||
Linux主机,有root权限。主机上最好安装了iptables命令(apt/yum很容易安装)。在windows和mac上可以开虚拟机(桥接模式和<del>NAT模式</del>经测试都可用)。
|
||||
|
||||
### 安装
|
||||
下载编译好的二进制文件,解压到任意目录。
|
||||
|
||||
@@ -60,16 +67,22 @@ https://github.com/wangyu-/udp2raw-tunnel/releases
|
||||
假设你有一个server,ip为44.55.66.77,有一个服务监听在udp 7777端口。 假设你本地的主机到44.55.66.77的UDP流量被屏蔽了,或者被qos了
|
||||
|
||||
```
|
||||
在client端运行:
|
||||
./udp2raw_amd64 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -a -k "passwd" --raw-mode faketcp
|
||||
|
||||
在server端运行:
|
||||
./udp2raw_amd64 -s -l0.0.0.0:4096 -r 127.0.0.1:7777 -a -k "passwd" --raw-mode faketcp
|
||||
|
||||
在client端运行:
|
||||
./udp2raw_amd64 -c -l0.0.0.0:3333 -r44.55.66.77:4096 -a -k "passwd" --raw-mode faketcp
|
||||
```
|
||||
###### Server端输出:
|
||||

|
||||
###### Client端输出:
|
||||

|
||||
|
||||
现在client和server之间建立起了,tunnel。想要在本地连接44.55.66.77:7777,只需要连接 127.0.0.1:3333。来回的所有的udp流量会被经过tunneling发送。在外界看起来是tcp流量,不会有udp流量暴露到公网。
|
||||
|
||||
### 提醒
|
||||
如果要在anroid上运行,请看[Android简明教程](/doc/android_guide.md)
|
||||
|
||||
# 进阶操作说明
|
||||
|
||||
### 命令选项
|
||||
|
29
doc/android_guide.md
Normal file
29
doc/android_guide.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# How to run udp2raw on a rooted android device(arm cpu)
|
||||
|
||||
There is currently no GUI for udp2raw on android.Make sure you have installed Terminal to run it.
|
||||
|
||||
Download udp2raw_arm from https://github.com/wangyu-/udp2raw-tunnel/releases.
|
||||
|
||||
Copy udp2raw_arm to any dir of your **internal storage** .Copying it to **SD card wont work**.
|
||||
|
||||
# Steps
|
||||
1. run udp2raw_arm as usual, except you must change the -a option to -g
|
||||
```
|
||||
./udp2raw_arm -c -r 44.55.66.77:9966 -l 0.0.0.0:4000 -k1234 --cipher xor -g
|
||||
```
|
||||
|
||||
2. find the generated iptables rule from udp2raw's output,add it manually by running:
|
||||
```
|
||||
iptables -I INPUT -s 44.55.66.77/32 -p tcp -m tcp --sport 9966 -j DROP
|
||||
```
|
||||
|
||||
3. run udp2raw_ram without -g command
|
||||
|
||||
```
|
||||
./udp2raw_arm -c -r 44.55.66.77:9966 -l 0.0.0.0:4000 -k1234 --cipher xor
|
||||
```
|
||||
|
||||
# ScreenShot
|
||||
zoom-in if not large enough
|
||||
|
||||

|
@@ -8,7 +8,7 @@
|
||||
##### 摘要
|
||||
udp2raw是一个把udp流量通过raw socket包装成tcp流量的工具。通过用udp2raw配合udp模式的 finalspeed一样可以达到在底层发tcp包,绕过QOS的效果。支持openvz,稳定性也好很多。原理上相当于在finalspeed外面再包了一层tunnel。
|
||||
|
||||
本教程会一步一步演示用udp2raw+kcptun加速http流量的过程。加速任何其他tcp流量也一样。
|
||||
本教程会一步一步演示用udp2raw+finalspeed加速http流量的过程。加速任何其他tcp流量也一样,包括ss。本文避免讨论科学上网,所以只演示加速http流量。
|
||||
|
||||
udp2raw也支持把udp流量包装成Icmp发送,本教程不做演示。
|
||||
|
||||
@@ -17,12 +17,14 @@ udp2raw也支持把udp流量包装成Icmp发送,本教程不做演示。
|
||||
|
||||
本地主机是windows,本地有openwrt路由器或树莓派或安装了linux虚拟机(网卡设置为桥接模式)。
|
||||
|
||||
(如果嫌给虚拟机安装linux麻烦,可以下载别人提供好的linux虚拟机镜像,比如https://www.kali.org/downloads/ ,不过我没有测试过这个镜像,我用的是debian 7)
|
||||
(如果嫌给虚拟机安装linux麻烦,可以用release里发布的预装了udp2raw的openwrt_x86虚拟机镜像,容量4.4mb)
|
||||
|
||||
下面的教程按虚拟机演示,如果你有openwrt路由器或树莓派,可以直接运行再路由器或树莓派上,就不需要虚拟机了。
|
||||
|
||||
### 安装
|
||||
下载好udp2raw的压缩包,解压分别解压到服务器和本地的虚拟机。
|
||||
|
||||
https://github.com/xtaci/kcptun/releases
|
||||
https://github.com/wangyu-/udp2raw-tunnel/releases
|
||||
|
||||
在服务器端安装好finalspeed服务端,在本地windows安装好finalspeed的客户端。服务端我以前是用91yun的一键安装脚本安装的,没装过的可以去网上搜一键安装脚本。
|
||||
|
||||
@@ -52,7 +54,7 @@ netstat -nlp|grep java
|
||||
|
||||
记下红框中的ip,这是虚拟机的网卡ip
|
||||
|
||||
在server端也会显示server_reay
|
||||
在server端也会显示server_ready
|
||||

|
||||
|
||||
4.在本地windows,按图配置好finalspeed的客户端。注意,192.168.205.8改成你刚才记下来的IP,带宽也要按实际的填。传输协议要选UDP.
|
||||
|
@@ -4,7 +4,9 @@
|
||||
本教程会一步一步演示用udp2raw+kcptun加速SSH流量的过程。加速任何其他tcp流量也一样,包括ss;本文避免涉及科学上网,所以演示ssh。
|
||||
|
||||
### 环境要求
|
||||
两边的主机都是linux,有root权限。 可以是openwrt路由器或树莓派,windows上桥接模式的虚拟机也可用
|
||||
两边的主机都是linux,有root权限。 可以是openwrt路由器或树莓派,也可以是root了的android。
|
||||
|
||||
(windows和mac可以用release里发布的预装了udp2raw的openwrt_x86虚拟机镜像,容量4.4mb,开机即用)
|
||||
|
||||
|
||||
### 安装
|
||||
|
11
encrypt.cpp
11
encrypt.cpp
@@ -11,12 +11,15 @@
|
||||
//static uint64_t seq=1;
|
||||
|
||||
static int8_t zero_iv[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0};//this prog use zero iv,you should make sure first block of data contains a random/nonce data
|
||||
|
||||
|
||||
/****
|
||||
* important!
|
||||
* why zero iv + nonce first data block is secure?
|
||||
* https://crypto.stackexchange.com/questions/5421/using-cbc-with-a-fixed-iv-and-a-random-first-plaintext-block
|
||||
****/
|
||||
unordered_map<int, const char *> auth_mode_tostring = {{auth_none, "none"}, {auth_md5, "md5"}, {auth_crc32, "crc32"},{auth_simple,"simple"}};
|
||||
unordered_map<int, const char *> cipher_mode_tostring={{cipher_none,"none"},{cipher_aes128cbc,"aes128cbc"},{cipher_xor,"xor"}};
|
||||
|
||||
auth_mode_t auth_mode=auth_crc32;
|
||||
auth_mode_t auth_mode=auth_md5;
|
||||
cipher_mode_t cipher_mode=cipher_aes128cbc;
|
||||
|
||||
|
||||
@@ -213,7 +216,7 @@ int auth_crc32_verify(const char *data,int &len)
|
||||
{
|
||||
if(len<int(sizeof(unsigned int)))
|
||||
{
|
||||
mylog(log_debug,"auth_crc32_verify len<16\n");
|
||||
mylog(log_debug,"auth_crc32_verify len<%d\n",int(sizeof(unsigned int)));
|
||||
return -1;
|
||||
}
|
||||
unsigned int ret=crc32h((unsigned char *)data,len-sizeof(unsigned int));
|
||||
|
BIN
images/android.png
Normal file
BIN
images/android.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 366 KiB |
BIN
images/output_client.PNG
Normal file
BIN
images/output_client.PNG
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
images/output_server.PNG
Normal file
BIN
images/output_server.PNG
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
BIN
images/speed_test.PNG
Normal file
BIN
images/speed_test.PNG
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
175
main.cpp
175
main.cpp
@@ -3,8 +3,10 @@
|
||||
#include "log.h"
|
||||
#include "lib/md5.h"
|
||||
|
||||
char local_address[100]="0.0.0.0", remote_address[100]="255.255.255.255",source_address[100]="0.0.0.0";
|
||||
u32_t local_address_uint32,remote_address_uint32,source_address_uint32;
|
||||
char local_ip[100]="0.0.0.0", remote_ip[100]="255.255.255.255",source_ip[100]="0.0.0.0";
|
||||
u32_t local_ip_uint32,remote_ip_uint32,source_ip_uint32;
|
||||
|
||||
int force_source_ip=0;
|
||||
int source_port=0,local_port = -1, remote_port = -1;
|
||||
|
||||
id_t const_id=0;
|
||||
@@ -234,6 +236,8 @@ struct conv_manager_t //TODO change map to unordered map
|
||||
int size=conv_last_active_time.size();
|
||||
int num_to_clean=size/conv_clear_ratio+conv_clear_min; //clear 1/10 each time,to avoid latency glitch
|
||||
|
||||
num_to_clean=min(num_to_clean,size);
|
||||
|
||||
u64_t current_time=get_current_time();
|
||||
for(;;)
|
||||
{
|
||||
@@ -860,12 +864,12 @@ int try_to_list_and_bind(int port)
|
||||
close(old_bind_fd);
|
||||
}
|
||||
|
||||
struct sockaddr_in temp_bind_addr;
|
||||
bzero(&temp_bind_addr, sizeof(temp_bind_addr));
|
||||
struct sockaddr_in temp_bind_addr={0};
|
||||
//bzero(&temp_bind_addr, sizeof(temp_bind_addr));
|
||||
|
||||
temp_bind_addr.sin_family = AF_INET;
|
||||
temp_bind_addr.sin_port = htons(port);
|
||||
temp_bind_addr.sin_addr.s_addr = local_address_uint32;
|
||||
temp_bind_addr.sin_addr.s_addr = local_ip_uint32;
|
||||
|
||||
if (bind(bind_fd, (struct sockaddr*)&temp_bind_addr, sizeof(temp_bind_addr)) !=0)
|
||||
{
|
||||
@@ -959,8 +963,7 @@ int set_timer_server(int epollfd,int &timer_fd)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int get_src_adress(u32_t &ip);
|
||||
int client_on_timer(conn_info_t &conn_info) //for client
|
||||
{
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
@@ -985,6 +988,18 @@ int client_on_timer(conn_info_t &conn_info) //for client
|
||||
conn_info.blob->anti_replay.re_init();
|
||||
conn_info.my_id = get_true_random_number_nz(); ///todo no need to do this everytime
|
||||
|
||||
u32_t new_ip=0;
|
||||
if(!force_source_ip&&get_src_adress(new_ip)==0)
|
||||
{
|
||||
if(new_ip!=source_ip_uint32)
|
||||
{
|
||||
mylog(log_info,"source ip changed from %s to",my_ntoa(source_ip_uint32));
|
||||
log_bare(log_info,"%s\n",my_ntoa(new_ip));
|
||||
source_ip_uint32=new_ip;
|
||||
send_info.src_ip=new_ip;
|
||||
}
|
||||
}
|
||||
|
||||
if (source_port == 0)
|
||||
{
|
||||
send_info.src_port = client_bind_to_a_new_port();
|
||||
@@ -1375,7 +1390,7 @@ int client_on_raw_recv(conn_info_t &conn_info)
|
||||
u64_t u64=conn_info.blob->conv_manager.find_u64_by_conv(tmp_conv_id);
|
||||
|
||||
|
||||
sockaddr_in tmp_sockaddr;
|
||||
sockaddr_in tmp_sockaddr={0};
|
||||
|
||||
tmp_sockaddr.sin_family = AF_INET;
|
||||
tmp_sockaddr.sin_addr.s_addr=(u64>>32u);
|
||||
@@ -1417,10 +1432,13 @@ int server_on_raw_recv_multi()
|
||||
{
|
||||
recv(raw_recv_fd, 0,0, 0 );//
|
||||
//struct sockaddr saddr;
|
||||
//socklen_t saddr_size;
|
||||
//socklen_t saddr_size=sizeof(saddr);
|
||||
///recvfrom(raw_recv_fd, 0,0, 0 ,&saddr , &saddr_size);//
|
||||
mylog(log_trace,"peek_raw failed\n");
|
||||
return -1;
|
||||
}else
|
||||
{
|
||||
mylog(log_trace,"peek_raw success\n");
|
||||
}
|
||||
u32_t ip=peek_info.src_ip;uint16_t port=peek_info.src_port;
|
||||
|
||||
@@ -1544,9 +1562,11 @@ int server_on_raw_recv_multi()
|
||||
if(conn_info.state.server_current_state==server_ready)
|
||||
{
|
||||
char type;
|
||||
//mylog(log_info,"before recv_safer\n");
|
||||
if (recv_safer(conn_info,type, data, data_len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
//mylog(log_info,"after recv_safer\n");
|
||||
return server_on_raw_recv_ready(conn_info,ip_port,type,data,data_len);
|
||||
}
|
||||
return 0;
|
||||
@@ -1663,13 +1683,13 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
|
||||
tmp_conv_id);
|
||||
return 0;
|
||||
}
|
||||
struct sockaddr_in remote_addr_in;
|
||||
struct sockaddr_in remote_addr_in={0};
|
||||
|
||||
socklen_t slen = sizeof(sockaddr_in);
|
||||
memset(&remote_addr_in, 0, sizeof(remote_addr_in));
|
||||
//memset(&remote_addr_in, 0, sizeof(remote_addr_in));
|
||||
remote_addr_in.sin_family = AF_INET;
|
||||
remote_addr_in.sin_port = htons(remote_port);
|
||||
remote_addr_in.sin_addr.s_addr = remote_address_uint32;
|
||||
remote_addr_in.sin_addr.s_addr = remote_ip_uint32;
|
||||
|
||||
int new_udp_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (new_udp_fd < 0) {
|
||||
@@ -1857,13 +1877,13 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info,char * ip_port,u32_t tmp
|
||||
|
||||
int get_src_adress(u32_t &ip)
|
||||
{
|
||||
struct sockaddr_in remote_addr_in;
|
||||
struct sockaddr_in remote_addr_in={0};
|
||||
|
||||
socklen_t slen = sizeof(sockaddr_in);
|
||||
memset(&remote_addr_in, 0, sizeof(remote_addr_in));
|
||||
//memset(&remote_addr_in, 0, sizeof(remote_addr_in));
|
||||
remote_addr_in.sin_family = AF_INET;
|
||||
remote_addr_in.sin_port = htons(remote_port);
|
||||
remote_addr_in.sin_addr.s_addr = remote_address_uint32;
|
||||
remote_addr_in.sin_addr.s_addr = remote_ip_uint32;
|
||||
|
||||
|
||||
int new_udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
@@ -1872,7 +1892,7 @@ int get_src_adress(u32_t &ip)
|
||||
mylog(log_warn,"create udp_fd error\n");
|
||||
return -1;
|
||||
}
|
||||
set_buf_size(new_udp_fd);
|
||||
//set_buf_size(new_udp_fd);
|
||||
|
||||
mylog(log_debug,"created new udp_fd %d\n",new_udp_fd);
|
||||
int ret = connect(new_udp_fd, (struct sockaddr *) &remote_addr_in, slen);
|
||||
@@ -1883,8 +1903,8 @@ int get_src_adress(u32_t &ip)
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_in my_addr;
|
||||
unsigned int len=sizeof(my_addr);
|
||||
struct sockaddr_in my_addr={0};
|
||||
socklen_t len=sizeof(my_addr);
|
||||
|
||||
if(getsockname(new_udp_fd, (struct sockaddr *) &my_addr, &len)!=0) return -1;
|
||||
|
||||
@@ -1894,6 +1914,7 @@ int get_src_adress(u32_t &ip)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int client_event_loop()
|
||||
{
|
||||
char buf[buf_len];
|
||||
@@ -1906,17 +1927,17 @@ int client_event_loop()
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
|
||||
//printf("?????\n");
|
||||
if(source_address_uint32==0)
|
||||
if(source_ip_uint32==0)
|
||||
{
|
||||
mylog(log_info,"get_src_adress called\n");
|
||||
if(get_src_adress(source_address_uint32)!=0)
|
||||
if(get_src_adress(source_ip_uint32)!=0)
|
||||
{
|
||||
mylog(log_fatal,"the trick to auto get source ip failed,you should specific an ip by --source-ip\n");
|
||||
myexit(-1);
|
||||
}
|
||||
}
|
||||
in_addr tmp;
|
||||
tmp.s_addr=source_address_uint32;
|
||||
tmp.s_addr=source_ip_uint32;
|
||||
mylog(log_info,"source ip = %s\n",inet_ntoa(tmp));
|
||||
//printf("done\n");
|
||||
|
||||
@@ -1927,13 +1948,13 @@ int client_event_loop()
|
||||
myexit(-1);
|
||||
}
|
||||
send_info.src_port=source_port;
|
||||
send_info.src_ip = source_address_uint32;
|
||||
send_info.src_ip = source_ip_uint32;
|
||||
|
||||
int i, j, k;int ret;
|
||||
init_raw_socket();
|
||||
|
||||
//init_filter(source_port);
|
||||
send_info.dst_ip=remote_address_uint32;
|
||||
send_info.dst_ip=remote_ip_uint32;
|
||||
send_info.dst_port=remote_port;
|
||||
|
||||
//g_packet_info.src_ip=source_address_uint32;
|
||||
@@ -1945,13 +1966,13 @@ int client_event_loop()
|
||||
int yes = 1;
|
||||
//setsockopt(udp_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
|
||||
|
||||
struct sockaddr_in local_me;
|
||||
struct sockaddr_in local_me={0};
|
||||
|
||||
socklen_t slen = sizeof(sockaddr_in);
|
||||
memset(&local_me, 0, sizeof(local_me));
|
||||
//memset(&local_me, 0, sizeof(local_me));
|
||||
local_me.sin_family = AF_INET;
|
||||
local_me.sin_port = htons(local_port);
|
||||
local_me.sin_addr.s_addr = local_address_uint32;
|
||||
local_me.sin_addr.s_addr = local_ip_uint32;
|
||||
|
||||
|
||||
if (bind(udp_fd, (struct sockaddr*) &local_me, slen) == -1) {
|
||||
@@ -2033,9 +2054,10 @@ int client_event_loop()
|
||||
{
|
||||
|
||||
int recv_len;
|
||||
struct sockaddr_in udp_new_addr_in;
|
||||
struct sockaddr_in udp_new_addr_in={0};
|
||||
socklen_t udp_new_addr_len = sizeof(sockaddr_in);
|
||||
if ((recv_len = recvfrom(udp_fd, buf, max_data_len, 0,
|
||||
(struct sockaddr *) &udp_new_addr_in, &slen)) == -1) {
|
||||
(struct sockaddr *) &udp_new_addr_in, &udp_new_addr_len)) == -1) {
|
||||
mylog(log_error,"recv_from error,this shouldnt happen at client\n");
|
||||
myexit(1);
|
||||
};
|
||||
@@ -2119,7 +2141,7 @@ int server_event_loop()
|
||||
|
||||
int i, j, k;int ret;
|
||||
|
||||
bind_address_uint32=local_address_uint32;//only server has bind adress,client sets it to zero
|
||||
bind_address_uint32=local_ip_uint32;//only server has bind adress,client sets it to zero
|
||||
|
||||
|
||||
if(raw_mode==mode_faketcp)
|
||||
@@ -2131,12 +2153,12 @@ int server_event_loop()
|
||||
bind_fd=socket(AF_INET,SOCK_DGRAM,0);
|
||||
}
|
||||
|
||||
struct sockaddr_in temp_bind_addr;
|
||||
bzero(&temp_bind_addr, sizeof(temp_bind_addr));
|
||||
struct sockaddr_in temp_bind_addr={0};
|
||||
// bzero(&temp_bind_addr, sizeof(temp_bind_addr));
|
||||
|
||||
temp_bind_addr.sin_family = AF_INET;
|
||||
temp_bind_addr.sin_port = htons(local_port);
|
||||
temp_bind_addr.sin_addr.s_addr = local_address_uint32;
|
||||
temp_bind_addr.sin_addr.s_addr = local_ip_uint32;
|
||||
|
||||
if (bind(bind_fd, (struct sockaddr*)&temp_bind_addr, sizeof(temp_bind_addr)) !=0)
|
||||
{
|
||||
@@ -2313,7 +2335,8 @@ int server_event_loop()
|
||||
|
||||
if(recv_len<0)
|
||||
{
|
||||
mylog(log_debug,"udp fd,recv_len<0 continue\n");
|
||||
mylog(log_debug,"udp fd,recv_len<0 continue,%s\n",strerror(errno));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2347,7 +2370,26 @@ int server_event_loop()
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void process_lower_level()
|
||||
{
|
||||
if (strchr(optarg, '#') == 0) {
|
||||
mylog(log_fatal,
|
||||
"lower-level parameter invaild,check help page for format\n");
|
||||
myexit(-1);
|
||||
}
|
||||
lower_level = 1;
|
||||
u32_t hw[6];
|
||||
memset(hw, 0, sizeof(hw));
|
||||
sscanf(optarg, "%[^#]#%x:%x:%x:%x:%x:%x", if_name, &hw[0], &hw[1], &hw[2],
|
||||
&hw[3], &hw[4], &hw[5]);
|
||||
|
||||
mylog(log_warn,
|
||||
"make sure this is correct: if_name=<%s> dest_mac_adress=<%02x:%02x:%02x:%02x:%02x:%02x> \n",
|
||||
if_name, hw[0], hw[1], hw[2], hw[3], hw[4], hw[5]);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
dest_hw_addr[i] = uint8_t(hw[i]);
|
||||
}
|
||||
}
|
||||
void print_help()
|
||||
{
|
||||
printf("udp2raw-tunnel\n");
|
||||
@@ -2361,8 +2403,8 @@ void print_help()
|
||||
printf("common options,these options must be same on both side:\n");
|
||||
printf(" --raw-mode <string> avaliable values:faketcp(default),udp,icmp\n");
|
||||
printf(" -k,--key <string> password to gen symetric key,default:\"secret key\"\n");
|
||||
printf(" --auth-mode <string> avaliable values:aes128cbc(default),xor,none\n");
|
||||
printf(" --cipher-mode <string> avaliable values:md5(default),crc32,simple,none\n");
|
||||
printf(" --cipher-mode <string> avaliable values:aes128cbc(default),xor,none\n");
|
||||
printf(" --auth-mode <string> avaliable values:md5(default),crc32,simple,none\n");
|
||||
printf(" -a,--auto-rule auto add (and delete) iptables rule\n");
|
||||
printf(" -g,--gen-rule generate iptables rule then exit\n");
|
||||
printf(" --disable-anti-replay disable anti-replay,not suggested\n");
|
||||
@@ -2388,6 +2430,8 @@ void print_help()
|
||||
printf(" 1:increase every packet\n");
|
||||
printf(" 2:increase randomly, about every 3 packets (default)\n");
|
||||
// printf("\n");
|
||||
printf(" --lower-level <string> send packet at OSI level 2, format:'if_name#dest_mac_adress'\n");
|
||||
printf(" ie:'eth0#00:23:45:67:89:b9'.Beta.\n");
|
||||
printf(" -h,--help print this help message\n");
|
||||
|
||||
//printf("common options,these options must be same on both side\n");
|
||||
@@ -2472,7 +2516,7 @@ void process_arg(int argc, char *argv[])
|
||||
case 'l':
|
||||
no_l = 0;
|
||||
if (strchr(optarg, ':') != 0) {
|
||||
sscanf(optarg, "%[^:]:%d", local_address, &local_port);
|
||||
sscanf(optarg, "%[^:]:%d", local_ip, &local_port);
|
||||
if(local_port==22)
|
||||
{
|
||||
mylog(log_fatal,"port 22 not allowed\n");
|
||||
@@ -2487,7 +2531,7 @@ void process_arg(int argc, char *argv[])
|
||||
case 'r':
|
||||
no_r = 0;
|
||||
if (strchr(optarg, ':') != 0) {
|
||||
sscanf(optarg, "%[^:]:%d", remote_address, &remote_port);
|
||||
sscanf(optarg, "%[^:]:%d", remote_ip, &remote_port);
|
||||
if(remote_port==22)
|
||||
{
|
||||
mylog(log_fatal,"port 22 not allowed\n");
|
||||
@@ -2536,7 +2580,10 @@ void process_arg(int argc, char *argv[])
|
||||
mylog(log_debug,"option_index: %d\n",option_index);
|
||||
if(strcmp(long_options[option_index].name,"clear")==0)
|
||||
{
|
||||
int ret =system("iptables-save |grep udp2raw_dWRwMnJhdw|sed -n 's/^-A/iptables -D/p'|sh");
|
||||
char *output;
|
||||
//int ret =system("iptables-save |grep udp2raw_dWRwMnJhdw|sed -n 's/^-A/iptables -D/p'|sh");
|
||||
int ret =run_command("iptables -S|sed -n '/udp2raw_dWRwMnJhdw/p'|sed -n 's/^-A/iptables -D/p'|sh",output);
|
||||
|
||||
//system("iptables-save |grep udp2raw_dWRwMnJhdw|sed 's/^-A/iptables -D/'|sh");
|
||||
//system("iptables-save|grep -v udp2raw_dWRwMnJhdw|iptables-restore");
|
||||
mylog(log_info,"tried to clear all iptables rule created previously,return value %d\n",ret);
|
||||
@@ -2545,8 +2592,9 @@ void process_arg(int argc, char *argv[])
|
||||
else if(strcmp(long_options[option_index].name,"source-ip")==0)
|
||||
{
|
||||
mylog(log_debug,"parsing long option :source-ip\n");
|
||||
sscanf(optarg, "%s", source_address);
|
||||
mylog(log_debug,"source: %s\n",source_address);
|
||||
sscanf(optarg, "%s", source_ip);
|
||||
mylog(log_debug,"source: %s\n",source_ip);
|
||||
force_source_ip=1;
|
||||
}
|
||||
else if(strcmp(long_options[option_index].name,"source-port")==0)
|
||||
{
|
||||
@@ -2600,7 +2648,7 @@ void process_arg(int argc, char *argv[])
|
||||
}
|
||||
if(i==cipher_end)
|
||||
{
|
||||
mylog(log_fatal,"no such cipher_mode %s\n",optarg);
|
||||
|
||||
myexit(-1);
|
||||
}
|
||||
}
|
||||
@@ -2609,21 +2657,7 @@ void process_arg(int argc, char *argv[])
|
||||
}
|
||||
else if(strcmp(long_options[option_index].name,"lower-level")==0)
|
||||
{
|
||||
if(strchr(optarg,'#')==0)
|
||||
{
|
||||
mylog(log_fatal,"lower-level parameter invaild,should be if_name#mac_adress ,ie eth0#00:23:45:67:89:b9\n");
|
||||
myexit(-1);
|
||||
}
|
||||
lower_level=1;
|
||||
u32_t hw[6];
|
||||
memset(hw,0,sizeof(hw));
|
||||
sscanf(optarg,"%[^#]#%x:%x:%x:%x:%x:%x",if_name,&hw[0],&hw[1],&hw[2],&hw[3],&hw[4],&hw[5]);
|
||||
|
||||
mylog(log_warn,"make sure this is correct: ifname=<%s> gateway_hw_hd=<%x:%x:%x:%x:%x:%x> \n",if_name,hw[0],hw[1],hw[2],hw[3],hw[4],hw[5]);
|
||||
for(int i=0;i<6;i++)
|
||||
{
|
||||
oppsite_hw_addr[i]=uint8_t(hw[i]);
|
||||
}
|
||||
process_lower_level();
|
||||
}
|
||||
else if(strcmp(long_options[option_index].name,"disable-color")==0)
|
||||
{
|
||||
@@ -2709,11 +2743,11 @@ void process_arg(int argc, char *argv[])
|
||||
|
||||
log_bare(log_info,"key=%s ",key_string);
|
||||
|
||||
log_bare(log_info,"local_ip=%s ",local_address);
|
||||
log_bare(log_info,"local_ip=%s ",local_ip);
|
||||
log_bare(log_info,"local_port=%d ",local_port);
|
||||
log_bare(log_info,"remote_ip=%s ",remote_address);
|
||||
log_bare(log_info,"remote_ip=%s ",remote_ip);
|
||||
log_bare(log_info,"remote_port=%d ",remote_port);
|
||||
log_bare(log_info,"source_ip=%s ",source_address);
|
||||
log_bare(log_info,"source_ip=%s ",source_ip);
|
||||
log_bare(log_info,"source_port=%d ",source_port);
|
||||
|
||||
log_bare(log_info,"socket_buf_size=%d ",socket_buf_size);
|
||||
@@ -2727,17 +2761,17 @@ void iptables_rule()
|
||||
{
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
sprintf(rule,"INPUT -s %s/32 -p tcp -m tcp --sport %d -j DROP",remote_address,remote_port);
|
||||
sprintf(rule,"INPUT -s %s/32 -p tcp -m tcp --sport %d -j DROP",remote_ip,remote_port);
|
||||
//mylog(log_warn,"make sure you have run once: iptables -A INPUT -s %s/32 -p tcp -m tcp --sport %d -j DROP\n",remote_address,remote_port);
|
||||
}
|
||||
if(raw_mode==mode_udp)
|
||||
{
|
||||
sprintf(rule,"INPUT -s %s/32 -p udp -m udp --sport %d -j DROP",remote_address,remote_port);
|
||||
sprintf(rule,"INPUT -s %s/32 -p udp -m udp --sport %d -j DROP",remote_ip,remote_port);
|
||||
//mylog(log_warn,"make sure you have run once: iptables -A INPUT -s %s/32 -p udp -m udp --sport %d -j DROP\n",remote_address,remote_port);
|
||||
}
|
||||
if(raw_mode==mode_icmp)
|
||||
{
|
||||
sprintf(rule,"INPUT -s %s/32 -p icmp -j DROP",remote_address);
|
||||
sprintf(rule,"INPUT -s %s/32 -p icmp -j DROP",remote_ip);
|
||||
//mylog(log_warn,"make sure you have run once: iptables -A INPUT -s %s/32 -p icmp -j DROP\n",remote_address);
|
||||
}
|
||||
}
|
||||
@@ -2756,14 +2790,14 @@ void iptables_rule()
|
||||
}
|
||||
if(raw_mode==mode_icmp)
|
||||
{
|
||||
if(local_address_uint32==0)
|
||||
if(local_ip_uint32==0)
|
||||
{
|
||||
sprintf(rule,"INPUT -p icmp -j DROP");
|
||||
//mylog(log_warn,"make sure you have run once: iptables -A INPUT -p icmp -j DROP\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(rule,"INPUT -d %s/32 -p icmp -j DROP",local_address);
|
||||
sprintf(rule,"INPUT -d %s/32 -p icmp -j DROP",local_ip);
|
||||
//mylog(log_warn,"make sure you have run once: iptables -A INPUT -d %s/32 -p icmp -j DROP\n",local_address);
|
||||
}
|
||||
}
|
||||
@@ -2802,6 +2836,8 @@ void iptables_rule()
|
||||
}
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
//auto a=string_to_vec("a b c d ");
|
||||
//printf("%d\n",(int)a.size());
|
||||
//printf("%d %d %d %d",larger_than_u32(1,2),larger_than_u32(2,1),larger_than_u32(0xeeaaeebb,2),larger_than_u32(2,0xeeaaeebb));
|
||||
//assert(0==1);
|
||||
dup2(1, 2);//redirect stderr to stdout
|
||||
@@ -2813,9 +2849,14 @@ int main(int argc, char *argv[])
|
||||
|
||||
process_arg(argc,argv);
|
||||
|
||||
local_address_uint32=inet_addr(local_address);
|
||||
remote_address_uint32=inet_addr(remote_address);
|
||||
source_address_uint32=inet_addr(source_address);
|
||||
if(geteuid() != 0)
|
||||
{
|
||||
mylog(log_error,"root check failed,make sure you run this program with root,we can try to continue,but it will likely fail\n");
|
||||
}
|
||||
|
||||
local_ip_uint32=inet_addr(local_ip);
|
||||
remote_ip_uint32=inet_addr(remote_ip);
|
||||
source_ip_uint32=inet_addr(source_ip);
|
||||
|
||||
|
||||
//current_time_rough=get_current_time();
|
||||
|
42
makefile
42
makefile
@@ -1,37 +1,47 @@
|
||||
cc_cross=/home/wangyu/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-g++
|
||||
cc_cross=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-g++
|
||||
cc_local=g++
|
||||
cc_ar71xx=/home/wangyu/OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-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
|
||||
cc_arm=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-g++
|
||||
FLAGS= -std=c++11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers
|
||||
SOURCES=main.cpp lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp
|
||||
TAR=udp2raw_binaries.tar.gz udp2raw_amd64 udp2raw_x86 udp2raw_ar71xx udp2raw_bcm2708
|
||||
NAME=udp2raw
|
||||
TAR=${NAME}_binaries.tar.gz ${NAME}_amd64 ${NAME}_x86 ${NAME}_ar71xx ${NAME}_bcm2708 ${NAME}_arm
|
||||
|
||||
all:
|
||||
rm -f udp2raw
|
||||
${cc_local} -o udp2raw -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
rm -f ${NAME}
|
||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
fast:
|
||||
rm -f udp2raw
|
||||
${cc_local} -o udp2raw -I. ${SOURCES} ${FLAGS} -lrt
|
||||
rm -f ${NAME}
|
||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt
|
||||
debug:
|
||||
rm -f udp2raw
|
||||
${cc_local} -o udp2raw -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -D MY_DEBUG
|
||||
rm -f ${NAME}
|
||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -D MY_DEBUG
|
||||
|
||||
ar71xx:
|
||||
${cc_ar71xx} -o udp2raw_ar71xx -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
|
||||
${cc_ar71xx} -o ${NAME}_ar71xx -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
|
||||
bcm2708:
|
||||
${cc_bcm2708} -o udp2raw_bcm2708 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
${cc_bcm2708} -o ${NAME}_bcm2708 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
amd64:
|
||||
${cc_local} -o ${NAME}_amd64 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
x86:
|
||||
${cc_local} -o ${NAME}_x86 -I. ${SOURCES} ${FLAGS} -lrt -static -O3 -m32
|
||||
arm:
|
||||
${cc_cross} -o ${NAME}_arm -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
|
||||
cross:
|
||||
${cc_cross} -o udp2raw_cross -I. ${SOURCES} ${FLAGS} -lrt -static -lgcc_eh -O3
|
||||
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -O3
|
||||
|
||||
cross2:
|
||||
${cc_cross} -o udp2raw_cross -I. ${SOURCES} ${FLAGS} -lrt -O3
|
||||
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -lgcc_eh -O3
|
||||
|
||||
release: ar71xx bcm2708
|
||||
${cc_local} -o udp2raw_amd64 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
${cc_local} -o udp2raw_x86 -I. ${SOURCES} ${FLAGS} -lrt -m32 -static -O3
|
||||
cross3:
|
||||
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
|
||||
release: amd64 x86 ar71xx bcm2708 arm
|
||||
tar -zcvf ${TAR}
|
||||
|
||||
clean:
|
||||
rm -f ${TAR}
|
||||
rm -f udp2raw udp2raw_cross
|
||||
|
||||
|
45
network.cpp
45
network.cpp
@@ -24,7 +24,9 @@ int lower_level=0;
|
||||
int ifindex=-1;
|
||||
char if_name[100]="";
|
||||
|
||||
unsigned char oppsite_hw_addr[6]=
|
||||
unsigned short g_ip_id_counter=0;
|
||||
|
||||
unsigned char dest_hw_addr[6]=
|
||||
{0xff,0xff,0xff,0xff,0xff,0xff};
|
||||
//{0x00,0x23,0x45,0x67,0x89,0xb9};
|
||||
|
||||
@@ -162,6 +164,7 @@ packet_info_t::packet_info_t()
|
||||
int init_raw_socket()
|
||||
{
|
||||
|
||||
g_ip_id_counter=get_true_random_number()%65535;
|
||||
if(lower_level==0)
|
||||
{
|
||||
raw_send_fd = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
|
||||
@@ -306,7 +309,6 @@ int init_ifindex(char * if_name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
|
||||
{
|
||||
const packet_info_t &send_info=raw_info.send_info;
|
||||
@@ -316,19 +318,18 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
|
||||
struct iphdr *iph = (struct iphdr *) send_raw_ip_buf;
|
||||
memset(iph,0,sizeof(iphdr));
|
||||
|
||||
static unsigned short ip_id=1;
|
||||
|
||||
iph->ihl = sizeof(iphdr)/4; //we dont use ip options,so the length is just sizeof(iphdr)
|
||||
iph->version = 4;
|
||||
iph->tos = 0;
|
||||
|
||||
if(lower_level)
|
||||
{
|
||||
iph->id=0;
|
||||
//iph->id = htons (ip_id++); //Id of this packet
|
||||
//iph->id=0;
|
||||
iph->id = htons (g_ip_id_counter++); //Id of this packet
|
||||
}
|
||||
else
|
||||
iph->id = 0; //Id of this packet ,kernel will auto fill this if id is zero ,or really?????// todo //seems like there is a problem
|
||||
iph->id = htons (g_ip_id_counter++); //Id of this packet
|
||||
//iph->id = 0; //Id of this packet ,kernel will auto fill this if id is zero ,or really?????// todo //seems like there is a problem
|
||||
|
||||
iph->frag_off = htons(0x4000); //DF set,others are zero
|
||||
// iph->frag_off = htons(0x0000); //DF set,others are zero
|
||||
@@ -353,7 +354,7 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
|
||||
int ret;
|
||||
if(lower_level==0)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in sin={0};
|
||||
sin.sin_family = AF_INET;
|
||||
//sin.sin_port = htons(info.dst_port); //dont need this
|
||||
sin.sin_addr.s_addr = send_info.dst_ip;
|
||||
@@ -363,14 +364,14 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
|
||||
else
|
||||
{
|
||||
|
||||
struct sockaddr_ll addr;
|
||||
memset(&addr,0,sizeof(addr));
|
||||
struct sockaddr_ll addr={0};
|
||||
//memset(&addr,0,sizeof(addr));
|
||||
|
||||
addr.sll_family=AF_PACKET;
|
||||
addr.sll_ifindex=ifindex;
|
||||
addr.sll_halen=ETHER_ADDR_LEN;
|
||||
addr.sll_protocol=htons(ETH_P_IP);
|
||||
memcpy(addr.sll_addr,oppsite_hw_addr,ETHER_ADDR_LEN);
|
||||
memcpy(addr.sll_addr,dest_hw_addr,ETHER_ADDR_LEN);
|
||||
ret = sendto(raw_send_fd, send_raw_ip_buf, ip_tot_len , 0, (struct sockaddr *) &addr, sizeof (addr));
|
||||
}
|
||||
if(ret==-1)
|
||||
@@ -389,13 +390,15 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
|
||||
int peek_raw(packet_info_t &peek_info)
|
||||
{ static char peek_raw_buf[buf_len];
|
||||
char *ip_begin=peek_raw_buf+link_level_header_len;
|
||||
struct sockaddr saddr;
|
||||
socklen_t saddr_size;
|
||||
struct sockaddr saddr={0};
|
||||
socklen_t saddr_size=sizeof(saddr);
|
||||
int recv_len = recvfrom(raw_recv_fd, peek_raw_buf,max_data_len, MSG_PEEK ,&saddr , &saddr_size);//change max_data_len to something smaller,we only need header here
|
||||
iphdr * iph = (struct iphdr *) (ip_begin);
|
||||
//mylog(log_info,"recv_len %d\n",recv_len);
|
||||
if(recv_len<int(sizeof(iphdr)))
|
||||
{
|
||||
mylog(log_trace,"failed here %d %d\n",recv_len,int(sizeof(iphdr)));
|
||||
mylog(log_trace,"%s\n ",strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
peek_info.src_ip=iph->saddr;
|
||||
@@ -407,10 +410,17 @@ int peek_raw(packet_info_t &peek_info)
|
||||
{
|
||||
case mode_faketcp:
|
||||
{
|
||||
if(iph->protocol!=IPPROTO_TCP) return -1;
|
||||
if(iph->protocol!=IPPROTO_TCP)
|
||||
{
|
||||
mylog(log_trace,"failed here");
|
||||
return -1;
|
||||
}
|
||||
struct tcphdr *tcph=(tcphdr *)payload;
|
||||
if(recv_len<int( iphdrlen+sizeof(tcphdr) ))
|
||||
{
|
||||
mylog(log_trace,"failed here");
|
||||
return -1;
|
||||
}
|
||||
peek_info.src_port=ntohs(tcph->source);
|
||||
peek_info.syn=tcph->syn;
|
||||
break;
|
||||
@@ -445,11 +455,9 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
||||
static char recv_raw_ip_buf[buf_len];
|
||||
|
||||
iphdr * iph;
|
||||
struct sockaddr saddr;
|
||||
socklen_t saddr_size;
|
||||
saddr_size = sizeof(saddr);
|
||||
struct sockaddr saddr={0};
|
||||
socklen_t saddr_size = sizeof(saddr);
|
||||
int flag=0;
|
||||
|
||||
int recv_len = recvfrom(raw_recv_fd, recv_raw_ip_buf, max_data_len, flag ,&saddr , &saddr_size);
|
||||
|
||||
if(recv_len<0)
|
||||
@@ -481,6 +489,7 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
||||
|
||||
if(bind_address_uint32!=0 &&recv_info.dst_ip!=bind_address_uint32)
|
||||
{
|
||||
mylog(log_trace,"bind adress doenst match, dropped\n");
|
||||
//printf(" bind adress doenst match, dropped\n");
|
||||
return -1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user