mirror of
https://github.com/wangyu-/udp2raw.git
synced 2025-09-15 19:54:28 +08:00
Compare commits
80 Commits
20170826.0
...
20170918.0
Author | SHA1 | Date | |
---|---|---|---|
|
378449ee28 | ||
|
dcc722ff5e | ||
|
661b329930 | ||
|
0de85dd736 | ||
|
fb54df66e4 | ||
|
3cdac6d95c | ||
|
9c51c14ad6 | ||
|
36d6854a57 | ||
|
b239e94342 | ||
|
86483be894 | ||
|
1c831f2911 | ||
|
d250528d29 | ||
|
0de39f1aae | ||
|
09b1cadb45 | ||
|
cf5774d2f4 | ||
|
2810a72a72 | ||
|
f8e64b03de | ||
|
2a4f50a6c6 | ||
|
82771f9e39 | ||
|
9a959c2dcf | ||
|
206dd1565c | ||
|
515d4e1dd8 | ||
|
adbe7d110f | ||
|
0fe1a3d38c | ||
|
9472fe8bb3 | ||
|
a8e5df4b35 | ||
|
cf5babd748 | ||
|
a235a7176e | ||
|
5ef9d3fefa | ||
|
bc3801e17d | ||
|
178327c581 | ||
|
698504aca0 | ||
|
934a65e7bf | ||
|
c8113ccb06 | ||
|
5e8269f8f5 | ||
|
f34d9b2820 | ||
|
6f107ec475 | ||
|
5651efd165 | ||
|
0aba2ab7ba | ||
|
106ac96671 | ||
|
1b72661b49 | ||
|
fc796641a1 | ||
|
91904d6311 | ||
|
3cbad7df23 | ||
|
7fa5b90be8 | ||
|
6c865cc5ab | ||
|
215f2a82f2 | ||
|
063931d1c1 | ||
|
ff6f4b4005 | ||
|
065f4d73fa | ||
|
64f97299a2 | ||
|
67cb1356e4 | ||
|
0cc72802e6 | ||
|
44eb464182 | ||
|
9c64891b28 | ||
|
51bbaa0627 | ||
|
d3290a9a94 | ||
|
9c9c549bd1 | ||
|
c0c7bfda68 | ||
|
87483d2f0d | ||
|
6ef15f0185 | ||
|
16a9b3ba89 | ||
|
1a999fd96d | ||
|
c8694bf080 | ||
|
c467ad5c38 | ||
|
241baede16 | ||
|
d2ebcf6f6d | ||
|
dc52499818 | ||
|
56d4287fc2 | ||
|
d4e2c28cce | ||
|
535642684b | ||
|
cb334f37f0 | ||
|
11ebd6f2ee | ||
|
bd1e7fbc2f | ||
|
1f94c40ccf | ||
|
05156c9366 | ||
|
75e0a7f40a | ||
|
42fb66894f | ||
|
7c4e39cf20 | ||
|
01a1d2b006 |
64
README.md
64
README.md
@@ -1,9 +1,12 @@
|
||||
# Udp2raw-tunnel
|
||||

|
||||
|
||||
A Tunnel which tunnels UDP via FakeTCP/UDP/ICMP Traffic by using Raw Socket, helps you Bypass UDP FireWalls(or Unstable UDP Environment). Its Encrypted, Anti-Replay and Multiplexed. It also acts as a Connection Stabilizer.
|
||||
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.
|
||||
|
||||
[简体中文](/doc/README.zh-cn.md)
|
||||
|
||||
# Support Platforms
|
||||
Linux host (including desktop Linux,Android phone/tablet,OpenWRT router,or Raspberry PI) with root access.
|
||||
|
||||
@@ -43,6 +46,22 @@ For example, if you use udp2raw + OpenVPN, OpenVPN won't lose connection after a
|
||||
### Keywords
|
||||
`Bypass 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`
|
||||
|
||||
# Frequently Asked Questions
|
||||
### Q: What is the advantage of using udp2raw FakeTCP mode,why not use a TCP-based VPN(such as OpenVPN TCP mode)?
|
||||
Answer: **TCP doesnt allow real-time/out-of-order delivery**. **If you use OpenVPN TCP mode to turn UDP traffic into TCP,there will be latency issue**:the loss of a single packet blocks all following packet until re-transmission is done. This will cause unacceptable delay for gaming and voice chatting.
|
||||
|
||||
**TCP also has re-transmission and congestion control which cant be disabled.** UDP programs usualy want to control packet sending rate by themselves. If you use OpenVPN TCP mode this cant be done because of the congestion control of underlying TCP protocol. Further more,with the re-transmission of underlying TCP,**if you send too many udp packets via an OpenVPN TCP connection,the connection will become completely unusable for a while**(It will eventually recover as most of the re-transmission is done,but it wont be very soon).
|
||||
|
||||
Those issues exist for almost all TCP-based VPNs.
|
||||
|
||||
For udp2raw there is no underlying TCP protocol,udp2raw just add TCP headers to UDP packets directly by using raw socket. It supports real-time/out-of-order delivery,there is no re-transmission and congestion control. **Udp2raw doesnt have all above issues**.
|
||||
|
||||
### Q: Is udp2raw designed for replacing VPN?
|
||||
Answer: No. Udp2raw is designed for bypassing UDP restrictions. It doesnt have all of the features a VPN has(such as transparently redirect all traffic).
|
||||
|
||||
Instead of replacing VPN,udp2raw can be used with any UDP-based VPN together to grant UDP-based VPN the ablity of bypassing UDP restrictions,while not having the performance issue involved by a TCP-based VPN. Check [this link](https://github.com/wangyu-/udp2raw-tunnel#tunneling-any-traffic-via-raw-traffic-by-using-udp2raw-openvpn) for more info.
|
||||
|
||||
|
||||
# Getting Started
|
||||
### Installing
|
||||
Download binary release from https://github.com/wangyu-/udp2raw-tunnel/releases
|
||||
@@ -67,11 +86,15 @@ Now,an encrypted raw tunnel has been established between client and server throu
|
||||
### Note
|
||||
To run on Android, check [Android_Guide](/doc/android_guide.md)
|
||||
|
||||
If you have connection problems.Take a look at `--seq-mode` option.
|
||||
|
||||
You can run udp2raw with a non-root account(for better security).Take a look at [#26](https://github.com/wangyu-/udp2raw-tunnel/issues/26) for more info.
|
||||
|
||||
# Advanced Topic
|
||||
### Usage
|
||||
```
|
||||
udp2raw-tunnel
|
||||
version: Aug 18 2017 00:29:11
|
||||
git version:adbe7d110f build date:Sep 6 2017 05:37:45
|
||||
repository: https://github.com/wangyu-/udp2raw-tunnel
|
||||
|
||||
usage:
|
||||
@@ -84,14 +107,16 @@ common options,these options must be same on both side:
|
||||
--cipher-mode <string> avaliable values:aes128cbc(default),xor,none
|
||||
--auth-mode <string> avaliable values:md5(default),crc32,simple,none
|
||||
-a,--auto-rule auto add (and delete) iptables rule
|
||||
-g,--gen-rule generate iptables rule then exit
|
||||
-g,--gen-rule generate iptables rule then exit,so that you can copy and
|
||||
add it manually.overrides -a
|
||||
--disable-anti-replay disable anti-replay,not suggested
|
||||
client options:
|
||||
--source-ip <ip> force source-ip for raw socket
|
||||
--source-port <port> force source-port for raw socket,tcp/udp only
|
||||
this option disables port changing while re-connecting
|
||||
other options:
|
||||
--conf-file <string> read options from a configuration file instead of command line
|
||||
--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
|
||||
4:info (default) 5:debug 6:trace
|
||||
--log-position enable file name,function name,line number in log
|
||||
@@ -99,13 +124,22 @@ other options:
|
||||
--disable-bpf disable the kernel space filter,most time its not necessary
|
||||
unless you suspect there is a bug
|
||||
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
|
||||
--seqmode <number> seq increase mode for faketcp:
|
||||
0:dont increase
|
||||
1:increase every packet
|
||||
2:increase randomly, about every 3 packets (default)
|
||||
--lower-level <string> send packet at OSI level 2, format:'if_name#dest_mac_adress'
|
||||
ie:'eth0#00:23:45:67:89:b9'.Beta.
|
||||
--force-sock-buf bypass system limitation while setting sock-buf
|
||||
--seq-mode <number> seq increase mode for faketcp:
|
||||
0:static header,do not increase seq and ack_seq
|
||||
1:increase seq for every packet,simply ack last seq
|
||||
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
|
||||
--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
|
||||
--gen-add generate iptables rule and add it permanently,then exit.overrides -g
|
||||
--keep-rule monitor iptables and auto re-add if necessary.implys -a
|
||||
--clear clear any iptables rules added by this program.overrides everything
|
||||
-h,--help print this help message
|
||||
|
||||
```
|
||||
|
||||
### Iptables rules,`-a` and `-g`
|
||||
@@ -117,9 +151,17 @@ It is suggested to use `aes128cbc` + `md5` to obtain maximum security. If you wa
|
||||
### `--seq-mode`
|
||||
The FakeTCP mode does not behave 100% like a real tcp connection. ISPs may be able to distinguish the simulated tcp traffic from the real TCP traffic (though it's costly). seq-mode can help you change the seq increase behavior slightly. If you experience connection problems, try to change the value.
|
||||
|
||||
### `--lower-level`
|
||||
`--lower-level` allows you to send packet at OSI level 2(link level),so that you can bypass any local iptables rules. If you have a complicated iptables rules which conflicts with udp2raw and you cant(or too lazy to) edit the iptables rules,`--lower-level` can be very useful. Try `--lower-level auto` to auto detect the parameters,you can specify it manually if `auto` fails.
|
||||
|
||||
Manual format `if_name#dest_mac_adress`,ie:`eth0#00:23:45:67:89:b9`.
|
||||
|
||||
### `--keep-rule`
|
||||
Monitor iptables and auto re-add iptables rules(for blocking kernel tcp processing) if necessary.Especially useful when iptables rules may be cleared by other programs(for example,if you are using openwrt,everytime you changed and commited a setting,iptables rule may be cleared and re-constructed).
|
||||
|
||||
### `--conf-file`
|
||||
|
||||
You can also load options from a configuration file in order to keep secrets away from ps command.
|
||||
You can also load options from a configuration file in order to keep secrets away from `ps` command.
|
||||
|
||||
For example, rewrite the options for the above `server` example (in Getting Started section) into configuration file:
|
||||
|
||||
|
@@ -17,3 +17,4 @@ set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -W
|
||||
#set(CMAKE_LINK_LIBRARY_FLAG "-lrt")
|
||||
add_executable(udp2raw_cmake ${SOURCE_FILES})
|
||||
target_link_libraries(udp2raw_cmake rt)
|
||||
target_link_libraries(udp2raw_cmake pthread)
|
||||
|
54
common.cpp
54
common.cpp
@@ -15,6 +15,7 @@ int about_to_exit=0;
|
||||
raw_mode_t raw_mode=mode_faketcp;
|
||||
unordered_map<int, const char*> raw_mode_tostring = {{mode_faketcp, "faketcp"}, {mode_udp, "udp"}, {mode_icmp, "icmp"}};
|
||||
int socket_buf_size=1024*1024;
|
||||
int force_socket_buf=0;
|
||||
|
||||
static int random_number_fd=-1;
|
||||
string iptables_pattern="";
|
||||
@@ -302,7 +303,7 @@ void setnonblocking(int sock) {
|
||||
/*
|
||||
Generic checksum calculation function
|
||||
*/
|
||||
unsigned short csum(const unsigned short *ptr,int nbytes) {
|
||||
unsigned short csum(const unsigned short *ptr,int nbytes) {//works both for big and little endian
|
||||
register long sum;
|
||||
unsigned short oddbyte;
|
||||
register short answer;
|
||||
@@ -325,18 +326,35 @@ unsigned short csum(const unsigned short *ptr,int nbytes) {
|
||||
return(answer);
|
||||
}
|
||||
|
||||
|
||||
int set_buf_size(int fd)
|
||||
{
|
||||
if(setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_SNDBUFFORCE fail,fd %d\n",fd);
|
||||
myexit(1);
|
||||
}
|
||||
if(setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_RCVBUFFORCE fail,fd %d\n",fd);
|
||||
myexit(1);
|
||||
}
|
||||
if(force_socket_buf)
|
||||
{
|
||||
if(setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_SNDBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||
myexit(1);
|
||||
}
|
||||
if(setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_RCVBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||
myexit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_SNDBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||
myexit(1);
|
||||
}
|
||||
if(setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_RCVBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||
myexit(1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -385,9 +403,15 @@ int numbers_to_char(id_t id1,id_t id2,id_t id3,char * &data,int &len)
|
||||
int char_to_numbers(const char * data,int len,id_t &id1,id_t &id2,id_t &id3)
|
||||
{
|
||||
if(len<int(sizeof(id_t)*3)) return -1;
|
||||
id1=ntohl( *((id_t*)(data+0)) );
|
||||
id2=ntohl( *((id_t*)(data+sizeof(id_t))) );
|
||||
id3=ntohl( *((id_t*)(data+sizeof(id_t)*2)) );
|
||||
//id1=ntohl( *((id_t*)(data+0)) );
|
||||
memcpy(&id1,data+0,sizeof(id1));
|
||||
id1=ntohl(id1);
|
||||
//id2=ntohl( *((id_t*)(data+sizeof(id_t))) );
|
||||
memcpy(&id2,data+sizeof(id_t),sizeof(id2));
|
||||
id2=ntohl(id2);
|
||||
//id3=ntohl( *((id_t*)(data+sizeof(id_t)*2)) );
|
||||
memcpy(&id3,data+sizeof(id_t)*2,sizeof(id3));
|
||||
id3=ntohl(id3);
|
||||
return 0;
|
||||
}
|
||||
int hex_to_u32(const string & a,u32_t &output)
|
||||
@@ -416,6 +440,8 @@ int hex_to_u32_with_endian(const string & a,u32_t &output)
|
||||
return -1;
|
||||
}
|
||||
bool larger_than_u32(u32_t a,u32_t b)
|
||||
//TODO
|
||||
//looks like this can simply be done by return ((i32_t)(a-b) >0)
|
||||
{
|
||||
|
||||
u32_t smaller,bigger;
|
||||
|
37
common.h
37
common.h
@@ -5,8 +5,8 @@
|
||||
* Author: wangyu
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
#ifndef UDP2RAW_COMMON_H_
|
||||
#define UDP2RAW_COMMON_H_
|
||||
#define __STDC_FORMAT_MACROS 1
|
||||
#include <inttypes.h>
|
||||
|
||||
@@ -63,39 +63,39 @@ const int max_data_len=1600;
|
||||
const int buf_len=max_data_len+400;
|
||||
const u32_t max_handshake_conn_num=10000;
|
||||
const u32_t max_ready_conn_num=1000;
|
||||
const u32_t anti_replay_window_size=1000;
|
||||
const u32_t anti_replay_window_size=4000;
|
||||
const int max_conv_num=10000;
|
||||
|
||||
const u32_t client_handshake_timeout=5000;
|
||||
const u32_t client_retry_interval=1000;
|
||||
const u32_t client_handshake_timeout=5000;//unit ms
|
||||
const u32_t client_retry_interval=1000;//ms
|
||||
|
||||
const u32_t server_handshake_timeout=10000;// this should be much longer than clients. client retry initially ,server retry passtively
|
||||
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_min=5;
|
||||
const int conv_clear_min=1;
|
||||
const int conn_clear_min=1;
|
||||
|
||||
const u32_t conv_clear_interval=1000;
|
||||
const u32_t conn_clear_interval=1000;
|
||||
const u32_t conv_clear_interval=3000;//ms
|
||||
const u32_t conn_clear_interval=3000;//ms
|
||||
|
||||
|
||||
const i32_t max_fail_time=0;//disable
|
||||
|
||||
const u32_t heartbeat_interval=1000;
|
||||
const u32_t heartbeat_interval=1000;//ms
|
||||
|
||||
const u32_t timer_interval=400;//this should be smaller than heartbeat_interval and retry interval;
|
||||
const u32_t timer_interval=400;//ms. this should be smaller than heartbeat_interval and retry interval;
|
||||
|
||||
//const uint32_t conv_timeout=120000; //120 second
|
||||
const u32_t conv_timeout=30000; //for test
|
||||
const uint32_t conv_timeout=120000; //ms. 120 second
|
||||
//const u32_t conv_timeout=30000; //for test
|
||||
|
||||
const u32_t client_conn_timeout=10000;
|
||||
const u32_t client_conn_uplink_timeout=client_conn_timeout+2000;
|
||||
const u32_t client_conn_timeout=15000;//ms.
|
||||
const u32_t client_conn_uplink_timeout=client_conn_timeout+2000;//ms
|
||||
|
||||
//const uint32_t server_conn_timeout=conv_timeout+60000;//this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth
|
||||
const u32_t server_conn_timeout=conv_timeout+10000;//for test
|
||||
const uint32_t server_conn_timeout=conv_timeout+60000;//ms. this should be 60s+ longer than conv_timeout,so that conv_manager can destruct convs gradually,to avoid latency glicth
|
||||
//const u32_t server_conn_timeout=conv_timeout+10000;//for test
|
||||
|
||||
//const u32_t iptables_rule_keep_interval=4000;
|
||||
const u32_t iptables_rule_keep_interval=15;//unit: second;
|
||||
|
||||
extern int about_to_exit;
|
||||
extern pthread_t keep_thread;
|
||||
@@ -107,6 +107,7 @@ enum program_mode_t {unset_mode=0,client_mode,server_mode};
|
||||
extern program_mode_t program_mode;
|
||||
extern unordered_map<int, const char*> raw_mode_tostring ;
|
||||
extern int socket_buf_size;
|
||||
extern int force_socket_buf;
|
||||
|
||||
typedef u32_t id_t;
|
||||
|
||||
|
@@ -83,12 +83,17 @@ https://github.com/wangyu-/udp2raw-tunnel/releases
|
||||
### 提醒
|
||||
如果要在anroid上运行,请看[Android简明教程](/doc/android_guide.md)
|
||||
|
||||
如果要在梅林固件的路由器上使用,添加`--lower-level auto` `--keep-rule`
|
||||
|
||||
如果client和server无法连接,或者连接经常断开,请看一下`--seq-mode`的用法,尝试不同的seq-mode。
|
||||
|
||||
udp2raw可以用非root账号运行,这样更安全。具体方法见:[#26](https://github.com/wangyu-/udp2raw-tunnel/issues/26)
|
||||
# 进阶操作说明
|
||||
|
||||
### 命令选项
|
||||
```
|
||||
udp2raw-tunnel
|
||||
version: Aug 18 2017 00:29:11
|
||||
git version:adbe7d110f build date:Sep 6 2017 05:37:45
|
||||
repository: https://github.com/wangyu-/udp2raw-tunnel
|
||||
|
||||
usage:
|
||||
@@ -101,13 +106,16 @@ common options,these options must be same on both side:
|
||||
--cipher-mode <string> avaliable values:aes128cbc(default),xor,none
|
||||
--auth-mode <string> avaliable values:md5(default),crc32,simple,none
|
||||
-a,--auto-rule auto add (and delete) iptables rule
|
||||
-g,--gen-rule generate iptables rule then exit
|
||||
-g,--gen-rule generate iptables rule then exit,so that you can copy and
|
||||
add it manually.overrides -a
|
||||
--disable-anti-replay disable anti-replay,not suggested
|
||||
client options:
|
||||
--source-ip <ip> force source-ip for raw socket
|
||||
--source-port <port> force source-port for raw socket,tcp/udp only
|
||||
this option disables port changing while re-connecting
|
||||
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
|
||||
4:info (default) 5:debug 6:trace
|
||||
--log-position enable file name,function name,line number in log
|
||||
@@ -115,13 +123,22 @@ other options:
|
||||
--disable-bpf disable the kernel space filter,most time its not necessary
|
||||
unless you suspect there is a bug
|
||||
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
|
||||
--seqmode <number> seq increase mode for faketcp:
|
||||
0:dont increase
|
||||
1:increase every packet
|
||||
2:increase randomly, about every 3 packets (default)
|
||||
--lower-level <string> send packet at OSI level 2, format:'if_name#dest_mac_adress'
|
||||
ie:'eth0#00:23:45:67:89:b9'.Beta.
|
||||
--force-sock-buf bypass system limitation while setting sock-buf
|
||||
--seq-mode <number> seq increase mode for faketcp:
|
||||
0:static header,do not increase seq and ack_seq
|
||||
1:increase seq for every packet,simply ack last seq
|
||||
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
|
||||
--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
|
||||
--gen-add generate iptables rule and add it permanently,then exit.overrides -g
|
||||
--keep-rule monitor iptables and auto re-add if necessary.implys -a
|
||||
--clear clear any iptables rules added by this program.overrides everything
|
||||
-h,--help print this help message
|
||||
|
||||
```
|
||||
|
||||
### iptables 规则,`-a`和`-g`
|
||||
@@ -134,16 +151,25 @@ other options:
|
||||
### `--seq-mode`
|
||||
facktcp模式并没有模拟tcp的全部。所以理论上有办法把faketcp和真正的tcp流量区分开来(虽然大部分ISP不太可能做这种程度的包检测)。seq-mode可以改变一些seq ack的行为。如果遇到了连接问题,可以尝试更改。在我这边的移动线路用3种模式都没问题。
|
||||
|
||||
### `--keep-rule`
|
||||
定期主动检查iptables,如果udp2raw添加的iptables规则丢了,就重新添加。在一些iptables可能会被其他程序清空的情况下(比如梅林固件和openwrt的路由器)格外有用。
|
||||
|
||||
### `--lower-level`
|
||||
大部分udp2raw不能连通的情况都是设置了不兼容的iptables造成的。--lower-level选项允许绕过本地iptables。在一些iptables不好改动的情况下尤其有效(比如你用的是梅林固件,iptables全是固件自己生成的)。
|
||||
|
||||
##### 格式
|
||||
`if_name#dest_mac_adress`,例如 `eth0#00:23:45:67:89:b9` 。`eth0`换成你的出口网卡名。`00:23:45:67:89:b9`换成网关的mac地址(如果client和server在同一个局域网内,可能不需要网关,这时候直接用对方主机的mac地址,这个属于罕见的应用场景,可以忽略)。
|
||||
|
||||
可以用`--lower-level auto`自动获取参数,如果获取参数失败,再手动填写。
|
||||
|
||||
##### client端获得--lower-level参数的办法
|
||||
在client 端,运行`traceroute <server_ip>`,记下第一跳的地址,这个就是`网关ip`。再运行`arp -s <网关ip>`,可以同时查到出口网卡名和mac。
|
||||
|
||||

|
||||
|
||||
如果traceroute第一跳结果是`* * *`,说明网关屏蔽了对traceroute的应答。需要用`ip route`或`route`查询网关:
|
||||
|
||||

|
||||
##### server端获得--lower-level参数的办法
|
||||
如果client有公网ip,就`traceroute <client_ip>`。下一步和client端的方法一样。
|
||||
|
||||
@@ -158,7 +184,7 @@ server端也可以用`--lower-level auto` 来尝试自动获得参数,如果
|
||||
|
||||
### `--conf-file`
|
||||
|
||||
为了避免将密码等私密信息暴露在进程命令行参数内,你也可以使用 `配置文件` 来存储参数。
|
||||
为了避免将密码等私密信息暴露给`ps`命令,你也可以使用 `配置文件` 来存储参数。
|
||||
|
||||
比如,将以上服务端参数改写成配置文件
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# 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.
|
||||
There is currently no GUI for udp2raw on android.Make sure you have installed Terminal to run it.Your device has to be rooted,otherwise you cant use raw socket.
|
||||
|
||||
Download udp2raw_arm from https://github.com/wangyu-/udp2raw-tunnel/releases.
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#### run at client side
|
||||
assume server ip is 45.66.77.88
|
||||
```
|
||||
./udp2raw_amd64 -s -l0.0.0.0:3333 -r 45.66.77.88:8855 -k "passwd" --raw-mode faketcp -a
|
||||
./udp2raw_amd64 -c -l0.0.0.0:3333 -r 45.66.77.88:8855 -k "passwd" --raw-mode faketcp -a
|
||||
```
|
||||
|
||||
#### hint
|
||||
|
30
encrypt.cpp
30
encrypt.cpp
@@ -16,6 +16,22 @@ 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
|
||||
* https://crypto.stackexchange.com/questions/5421/using-cbc-with-a-fixed-iv-and-a-random-first-plaintext-block
|
||||
****/
|
||||
|
||||
|
||||
/*
|
||||
TODO
|
||||
|
||||
Change md5 to HMAC-md5 if necessary.Change padding to PKCS#7 style if necessary.
|
||||
|
||||
Need someone with cryptography knowledge to help review the encryption method.
|
||||
|
||||
Change them if necessary(I can do this by myself,if it turns out to be necessary).
|
||||
|
||||
github issue:
|
||||
|
||||
https://github.com/wangyu-/udp2raw-tunnel/issues/17
|
||||
|
||||
*/
|
||||
|
||||
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"}};
|
||||
|
||||
@@ -192,6 +208,13 @@ int de_padding(const char *data ,int &data_len,int padding_num)
|
||||
}
|
||||
int cipher_aes128cbc_encrypt(const char *data,char *output,int &len,char * key)
|
||||
{
|
||||
static int first_time=1;
|
||||
if(aes_key_optimize)
|
||||
{
|
||||
if(first_time==0) key=0;
|
||||
else first_time=0;
|
||||
}
|
||||
|
||||
char buf[buf_len];
|
||||
memcpy(buf,data,len);//TODO inefficient code
|
||||
|
||||
@@ -237,7 +260,12 @@ int cipher_none_encrypt(const char *data,char *output,int &len,char * key)
|
||||
}
|
||||
int cipher_aes128cbc_decrypt(const char *data,char *output,int &len,char * key)
|
||||
{
|
||||
|
||||
static int first_time=1;
|
||||
if(aes_key_optimize)
|
||||
{
|
||||
if(first_time==0) key=0;
|
||||
else first_time=0;
|
||||
}
|
||||
if(len%16 !=0) {mylog(log_debug,"len%%16!=0\n");return -1;}
|
||||
//if(len<0) {mylog(log_debug,"len <0\n");return -1;}
|
||||
AES_CBC_decrypt_buffer((unsigned char *)output,(unsigned char *)data,len,(unsigned char *)key,(unsigned char *)zero_iv);
|
||||
|
14
encrypt.h
14
encrypt.h
@@ -1,5 +1,5 @@
|
||||
#ifndef _ENCRYPTION_H_
|
||||
#define _ENCRYPTION_H_
|
||||
#ifndef UDP2RAW_ENCRYPTION_H_
|
||||
#define UDP2RAW_ENCRYPTION_H_
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
|
||||
//using namespace std;
|
||||
|
||||
|
||||
const int aes_key_optimize=1; //if enabled,once you used a key for aes,you cant change it anymore
|
||||
|
||||
|
||||
int my_encrypt(const char *data,char *output,int &len,char * key);
|
||||
int my_decrypt(const char *data,char *output,int &len,char * key);
|
||||
|
||||
@@ -32,4 +36,10 @@ extern cipher_mode_t cipher_mode;
|
||||
extern unordered_map<int, const char *> auth_mode_tostring;
|
||||
extern unordered_map<int, const char *> cipher_mode_tostring;
|
||||
|
||||
|
||||
|
||||
|
||||
int cipher_decrypt(const char *data,char *output,int &len,char * key);//internal interface ,exposed for test only
|
||||
int cipher_encrypt(const char *data,char *output,int &len,char * key);//internal interface ,exposed for test only
|
||||
|
||||
#endif
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 22 KiB |
Binary file not shown.
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 26 KiB |
BIN
images/route.PNG
Normal file
BIN
images/route.PNG
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
@@ -2,8 +2,8 @@
|
||||
* this file comes from https://github.com/kokke/tiny-AES128-C
|
||||
*/
|
||||
|
||||
#ifndef _AES_H_
|
||||
#define _AES_H_
|
||||
#ifndef UDP2RAW_AES_H_
|
||||
#define UDP2RAW_AES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
@@ -340,30 +340,34 @@ int AES_support_hwaccel(void)
|
||||
void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
|
||||
{
|
||||
uint8_t iv_tmp[16];
|
||||
uint8_t rk[AES_RKSIZE];
|
||||
static uint8_t rk[AES_RKSIZE];
|
||||
|
||||
if (key == NULL || iv == NULL)
|
||||
if (iv == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
aeshw_init();
|
||||
memcpy(iv_tmp, iv, 16);
|
||||
setkey_enc(rk, key);
|
||||
if(key!= NULL)
|
||||
setkey_enc(rk, key);
|
||||
encrypt_cbc(rk, length, iv_tmp, input, output);
|
||||
}
|
||||
|
||||
void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
|
||||
{
|
||||
uint8_t iv_tmp[16];
|
||||
uint8_t rk[AES_RKSIZE];
|
||||
static uint8_t rk[AES_RKSIZE];
|
||||
|
||||
if (key == NULL || iv == NULL)
|
||||
if (iv == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
aeshw_init();
|
||||
memcpy(iv_tmp, iv, 16);
|
||||
setkey_dec(rk, key);
|
||||
if(key!= NULL)
|
||||
{
|
||||
setkey_dec(rk, key);
|
||||
}
|
||||
decrypt_cbc(rk, length, iv_tmp, input, output);
|
||||
}
|
||||
|
||||
|
@@ -26,8 +26,8 @@
|
||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||
*/
|
||||
|
||||
#ifndef _AESARM_H_
|
||||
#define _AESARM_H_
|
||||
#ifndef UDP2RAW_AESARM_H_
|
||||
#define UDP2RAW_AESARM_H_
|
||||
|
||||
#ifndef AES_ENCRYPT
|
||||
#define AES_ENCRYPT 1
|
||||
|
@@ -26,8 +26,8 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef _AESNI_H_
|
||||
#define _AESNI_H_
|
||||
#ifndef UDP2RAW_AESNI_H_
|
||||
#define UDP2RAW_AESNI_H_
|
||||
|
||||
#ifndef AES_ENCRYPT
|
||||
#define AES_ENCRYPT 1
|
||||
|
4
lib/aes_acc/asm/arm_arch.h
vendored
4
lib/aes_acc/asm/arm_arch.h
vendored
@@ -7,8 +7,8 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#ifndef __ARM_ARCH_H__
|
||||
# define __ARM_ARCH_H__
|
||||
#ifndef UDP2RAW_ARM_ARCH_H_
|
||||
# define UDP2RAW_ARM_ARCH_H_
|
||||
|
||||
# if !defined(__ARM_ARCH__)
|
||||
# if defined(__CC_ARM)
|
||||
|
1459
lib/aes_faster_c/aes.c
Normal file
1459
lib/aes_faster_c/aes.c
Normal file
File diff suppressed because it is too large
Load Diff
267
lib/aes_faster_c/aes.h
Normal file
267
lib/aes_faster_c/aes.h
Normal file
@@ -0,0 +1,267 @@
|
||||
/**
|
||||
* \file aes.h
|
||||
*
|
||||
* \brief AES block cipher
|
||||
*
|
||||
* Copyright (C) 2006-2014, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_AES_H
|
||||
#define POLARSSL_AES_H
|
||||
/*
|
||||
#if !defined(POLARSSL_CONFIG_FILE)
|
||||
#include "config.h"
|
||||
#else
|
||||
#include POLARSSL_CONFIG_FILE
|
||||
#endif
|
||||
*/
|
||||
|
||||
////////modification begin
|
||||
#define POLARSSL_AES_ROM_TABLES
|
||||
#define POLARSSL_CIPHER_MODE_CBC
|
||||
//#define POLARSSL_SELF_TEST
|
||||
#define polarssl_printf printf
|
||||
///////add end
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/* padlock.c and aesni.c rely on these values! */
|
||||
#define AES_ENCRYPT 1
|
||||
#define AES_DECRYPT 0
|
||||
|
||||
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
||||
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
||||
|
||||
#if !defined(POLARSSL_AES_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief AES context structure
|
||||
*
|
||||
* \note buf is able to hold 32 extra bytes, which can be used:
|
||||
* - for alignment purposes if VIA padlock is used, and/or
|
||||
* - to simplify key expansion in the 256-bit case by
|
||||
* generating an extra round key
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int nr; /*!< number of rounds */
|
||||
uint32_t *rk; /*!< AES round keys */
|
||||
uint32_t buf[68]; /*!< unaligned data */
|
||||
}
|
||||
aes_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize AES context
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
*/
|
||||
void aes_init( aes_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear AES context
|
||||
*
|
||||
* \param ctx AES context to be cleared
|
||||
*/
|
||||
void aes_free( aes_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief AES key schedule (encryption)
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
* \param key encryption key
|
||||
* \param keysize must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int aes_setkey_enc( aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief AES key schedule (decryption)
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
* \param key decryption key
|
||||
* \param keysize must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int aes_setkey_dec( aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief AES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param input 16-byte input block
|
||||
* \param output 16-byte output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_ecb( aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CBC)
|
||||
/**
|
||||
* \brief AES-CBC buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (16 bytes)
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
|
||||
*/
|
||||
int aes_crypt_cbc( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /* POLARSSL_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
/**
|
||||
* \brief AES-CFB128 buffer encryption/decryption.
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv_off offset in IV (updated after use)
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_cfb128( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief AES-CFB8 buffer encryption/decryption.
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_cfb8( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /*POLARSSL_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
/**
|
||||
* \brief AES-CTR buffer encryption/decryption
|
||||
*
|
||||
* Warning: You have to keep the maximum use of your counter in mind!
|
||||
*
|
||||
* Note: Due to the nature of CTR you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param length The length of the data
|
||||
* \param nc_off The offset in the current stream_block (for resuming
|
||||
* within current cipher stream). The offset pointer to
|
||||
* should be 0 at the start of a stream.
|
||||
* \param nonce_counter The 128-bit nonce and counter.
|
||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
||||
* by the function.
|
||||
* \param input The input data stream
|
||||
* \param output The output data stream
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_ctr( aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_AES_ALT */
|
||||
#include "aes_alt.h"
|
||||
#endif /* POLARSSL_AES_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int aes_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* aes.h */
|
56
lib/aes_faster_c/wrapper.c
Normal file
56
lib/aes_faster_c/wrapper.c
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "aes.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(AES256) && (AES256 == 1)
|
||||
#define AES_KEYSIZE 256
|
||||
#elif defined(AES192) && (AES192 == 1)
|
||||
#define AES_KEYSIZE 192
|
||||
#else
|
||||
#define AES_KEYSIZE 128
|
||||
#endif
|
||||
|
||||
|
||||
void AES_ECB_encrypt(const uint8_t* input, const uint8_t* key, uint8_t *output, const uint32_t length)
|
||||
{
|
||||
printf("AES_ECB_encrypt not implemented\n");
|
||||
exit(-1);
|
||||
}
|
||||
void AES_ECB_decrypt(const uint8_t* input, const uint8_t* key, uint8_t *output, const uint32_t length)
|
||||
{
|
||||
printf("AES_ECB_encrypt not implemented\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
|
||||
{
|
||||
static aes_context ctx;
|
||||
static int done=0;
|
||||
if(done==0)
|
||||
{
|
||||
aes_init( &ctx);
|
||||
done=1;
|
||||
}
|
||||
|
||||
char tmp_iv[16];
|
||||
if(key!=0) aes_setkey_enc(&ctx,key,AES_KEYSIZE);
|
||||
memcpy(tmp_iv,iv,16);
|
||||
aes_crypt_cbc( &ctx, AES_ENCRYPT, length, (unsigned char* )tmp_iv, (const unsigned char*)input,(unsigned char*) output );
|
||||
return ;
|
||||
}
|
||||
void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
|
||||
{
|
||||
static aes_context ctx;
|
||||
static int done=0;
|
||||
if(done==0)
|
||||
{
|
||||
aes_init( &ctx);
|
||||
done=1;
|
||||
}
|
||||
|
||||
char tmp_iv[16];
|
||||
if(key!=0) aes_setkey_dec(&ctx,key,AES_KEYSIZE);
|
||||
memcpy(tmp_iv,iv,16);
|
||||
aes_crypt_cbc( &ctx,AES_DECRYPT, length, (unsigned char*)tmp_iv, (const unsigned char*)input, (unsigned char*) output );
|
||||
return;
|
||||
}
|
12
lib/md5.c
12
lib/md5.c
@@ -302,11 +302,15 @@ void md5_finish( md5_context *ctx, unsigned char output[16] )
|
||||
*/
|
||||
void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
|
||||
{
|
||||
md5_context ctx;
|
||||
|
||||
md5_init( &ctx );
|
||||
static md5_context ctx;
|
||||
static int done=0;
|
||||
if(done==0)
|
||||
{
|
||||
md5_init( &ctx );
|
||||
done=1;
|
||||
}
|
||||
md5_starts( &ctx );
|
||||
md5_update( &ctx, input, ilen );
|
||||
md5_finish( &ctx, output );
|
||||
md5_free( &ctx );
|
||||
//md5_free( &ctx );
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef _MD5_H_
|
||||
#define _MD5_H_
|
||||
#ifndef UDP2RAW_MD5_H_
|
||||
#define UDP2RAW_MD5_H_
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
6
log.h
6
log.h
@@ -1,9 +1,9 @@
|
||||
|
||||
#ifndef _LOG_MYLOG_H_
|
||||
#define _LOG_MYLOG_H_
|
||||
#ifndef UDP2RAW_LOG_MYLOG_H_
|
||||
#define UDP2RAW_LOG_MYLOG_H_
|
||||
|
||||
|
||||
#include<common.h>
|
||||
#include "common.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
327
main.cpp
327
main.cpp
@@ -3,54 +3,57 @@
|
||||
#include "log.h"
|
||||
#include "lib/md5.h"
|
||||
#include "encrypt.h"
|
||||
#include "git_version.h"
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
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;
|
||||
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
|
||||
|
||||
int force_source_ip=0;
|
||||
int source_port=0,local_port = -1, remote_port = -1;
|
||||
|
||||
id_t const_id=0;
|
||||
int force_source_ip=0; //if --source-ip is enabled
|
||||
|
||||
|
||||
const int disable_conv_clear=0;
|
||||
const int disable_conn_clear=0;
|
||||
id_t const_id=0;//an id used for connection recovery,its generated randomly,it never change since its generated
|
||||
|
||||
|
||||
enum server_current_state_t {server_idle=0,server_handshake1,server_ready};
|
||||
enum client_current_state_t {client_idle=0,client_tcp_handshake,client_handshake1,client_handshake2,client_ready};
|
||||
const int disable_conv_clear=0;//a udp connection in the multiplexer is called conversation in this program,conv for short.
|
||||
|
||||
const int disable_conn_clear=0;//a raw connection is called conn.
|
||||
|
||||
|
||||
enum server_current_state_t {server_idle=0,server_handshake1,server_ready}; //server state machine
|
||||
enum client_current_state_t {client_idle=0,client_tcp_handshake,client_handshake1,client_handshake2,client_ready};//client state machine
|
||||
union current_state_t
|
||||
{
|
||||
server_current_state_t server_current_state;
|
||||
client_current_state_t client_current_state;
|
||||
};
|
||||
|
||||
int udp_fd=-1; //for client only
|
||||
int bind_fd=-1; //bind only,never send or recv
|
||||
int epollfd=-1;
|
||||
int timer_fd=-1;
|
||||
int fail_time_counter=0;
|
||||
int epoll_trigger_counter=0;
|
||||
int debug_flag=0;
|
||||
int udp_fd=-1; //for client only. client use this fd to listen and handle udp connection
|
||||
int bind_fd=-1; //bind only,never send or recv. its just a dummy fd for bind,so that other program wont occupy the same port
|
||||
int epollfd=-1; //fd for epoll
|
||||
int timer_fd=-1; //the general timer fd for client and server.for server this is not the only timer find,every connection has a timer fd.
|
||||
int fail_time_counter=0;//determine if the max_fail_time is reached
|
||||
int epoll_trigger_counter=0;//for debug only
|
||||
int debug_flag=0;//for debug only
|
||||
|
||||
|
||||
int simple_rule=0;
|
||||
int keep_rule=0;
|
||||
int auto_add_iptables_rule=0;
|
||||
int generate_iptables_rule=0;
|
||||
int generate_iptables_rule_add=0;
|
||||
int simple_rule=0; //deprecated.
|
||||
int keep_rule=0; //whether to monitor the iptables rule periodly,re-add if losted
|
||||
int auto_add_iptables_rule=0;//if -a is set
|
||||
int generate_iptables_rule=0;//if -g is set
|
||||
int generate_iptables_rule_add=0;// if --gen-add is set
|
||||
|
||||
int debug_resend=0;
|
||||
int disable_anti_replay=0;
|
||||
char key_string[1000]= "secret key";
|
||||
char key[16];//,key2[16];
|
||||
int debug_resend=0; // debug only
|
||||
int disable_anti_replay=0;//if anti_replay windows is diabled
|
||||
char key_string[1000]= "secret key";// -k option
|
||||
char key[16];//generated from key_string by md5.
|
||||
|
||||
int mtu_warn=1375;
|
||||
int mtu_warn=1375;//if a packet larger than mtu warn is receviced,there will be a warning
|
||||
|
||||
//uint64_t current_time_rough=0;
|
||||
|
||||
@@ -58,7 +61,7 @@ int mtu_warn=1375;
|
||||
int VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV;
|
||||
////////==============================variable divider=============================================================
|
||||
|
||||
struct anti_replay_t
|
||||
struct anti_replay_t //its for anti replay attack,similar to openvpn/ipsec 's anti replay window
|
||||
{
|
||||
u64_t max_packet_received;
|
||||
char window[anti_replay_window_size];
|
||||
@@ -121,7 +124,7 @@ struct anti_replay_t
|
||||
};//anti_replay;
|
||||
|
||||
void server_clear_function(u64_t u64);
|
||||
struct conv_manager_t //TODO change map to unordered map
|
||||
struct conv_manager_t // manage the udp connections
|
||||
{
|
||||
//typedef hash_map map;
|
||||
unordered_map<u64_t,u32_t> u64_to_conv; //conv and u64 are both supposed to be uniq
|
||||
@@ -284,12 +287,13 @@ struct conv_manager_t //TODO change map to unordered map
|
||||
return 0;
|
||||
}
|
||||
};//g_conv_manager;
|
||||
struct blob_t
|
||||
struct blob_t //used in conn_info_t. conv_manager_t and anti_replay_t are costly data structures ,we dont allocate them until its necessary
|
||||
{
|
||||
conv_manager_t conv_manager;
|
||||
anti_replay_t anti_replay;
|
||||
};
|
||||
struct conn_info_t
|
||||
struct conn_info_t //stores info for a raw connection.for client ,there is only one connection,for server there can be thousand of connection since server can
|
||||
//handle multiple clients
|
||||
{
|
||||
current_state_t state;
|
||||
|
||||
@@ -376,7 +380,7 @@ struct conn_info_t
|
||||
~conn_info_t();
|
||||
};//g_conn_info;
|
||||
|
||||
struct conn_manager_t
|
||||
struct conn_manager_t //manager for connections. for client,we dont need conn_manager since there is only one connection.for server we use one conn_manager for all connections
|
||||
{
|
||||
|
||||
u32_t ready_num;
|
||||
@@ -580,7 +584,8 @@ int find_lower_level_info(u32_t ip,u32_t &dest_ip,string &if_name,string &hw);
|
||||
int DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD;
|
||||
////////////////=======================declear divider=============================
|
||||
|
||||
void server_clear_function(u64_t u64)
|
||||
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;
|
||||
@@ -612,7 +617,8 @@ void server_clear_function(u64_t u64)
|
||||
|
||||
|
||||
|
||||
int send_bare(raw_info_t &raw_info,const char* data,int len)
|
||||
int send_bare(raw_info_t &raw_info,const char* data,int len)//send function with encryption but no anti replay,this is used when client and server verifys each other
|
||||
//you have to design the protocol carefully, so that you wont be affect by relay attack
|
||||
{
|
||||
if(len<0)
|
||||
{
|
||||
@@ -644,7 +650,7 @@ int send_bare(raw_info_t &raw_info,const char* data,int len)
|
||||
send_raw0(raw_info,send_data_buf2,new_len);
|
||||
return 0;
|
||||
}
|
||||
int parse_bare(const char *input,int input_len,char* & data,int & len) //allow overlap
|
||||
int reserved_parse_bare(const char *input,int input_len,char* & data,int & len) // a sub function used in recv_bare
|
||||
{
|
||||
static char recv_data_buf[buf_len];
|
||||
|
||||
@@ -673,7 +679,8 @@ int parse_bare(const char *input,int input_len,char* & data,int & len) //allow
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int recv_bare(raw_info_t &raw_info,char* & data,int & len)
|
||||
int recv_bare(raw_info_t &raw_info,char* & data,int & len)//recv function with encryption but no anti replay,this is used when client and server verifys each other
|
||||
//you have to design the protocol carefully, so that you wont be affect by relay attack
|
||||
{
|
||||
packet_info_t &send_info=raw_info.send_info;
|
||||
packet_info_t &recv_info=raw_info.recv_info;
|
||||
@@ -688,10 +695,10 @@ int recv_bare(raw_info_t &raw_info,char* & data,int & len)
|
||||
mylog(log_debug,"unexpect packet type recv_info.syn=%d recv_info.ack=%d \n",recv_info.syn,recv_info.ack);
|
||||
return -1;
|
||||
}
|
||||
return parse_bare(data,len,data,len);
|
||||
return reserved_parse_bare(data,len,data,len);
|
||||
}
|
||||
|
||||
int send_handshake(raw_info_t &raw_info,id_t id1,id_t id2,id_t id3)
|
||||
int send_handshake(raw_info_t &raw_info,id_t id1,id_t id2,id_t id3)// a warp for send_bare for sending handshake(this is not tcp handshake) easily
|
||||
{
|
||||
packet_info_t &send_info=raw_info.send_info;
|
||||
packet_info_t &recv_info=raw_info.recv_info;
|
||||
@@ -713,7 +720,7 @@ int recv_handshake(packet_info_t &info,id_t &id1,id_t &id2,id_t &id3)
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
int send_safer(conn_info_t &conn_info,char type,const char* data,int len)
|
||||
int send_safer(conn_info_t &conn_info,char type,const char* data,int len) //safer transfer function with anti-replay,when mutually verification is done.
|
||||
{
|
||||
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
@@ -763,7 +770,7 @@ int send_safer(conn_info_t &conn_info,char type,const char* data,int len)
|
||||
|
||||
return 0;
|
||||
}
|
||||
int send_data_safer(conn_info_t &conn_info,const char* data,int len,u32_t conv_num)
|
||||
int send_data_safer(conn_info_t &conn_info,const char* data,int len,u32_t conv_num)//a wrap for send_safer for transfer data.
|
||||
{
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
@@ -779,11 +786,11 @@ int send_data_safer(conn_info_t &conn_info,const char* data,int len,u32_t conv_n
|
||||
return 0;
|
||||
|
||||
}
|
||||
int parse_safer(conn_info_t &conn_info,const char * input,int input_len,char &type,char* &data,int &len)//allow overlap
|
||||
int parse_safer(conn_info_t &conn_info,const char * input,int input_len,char &type,char* &data,int &len)//subfunction for recv_safer,allow overlap
|
||||
{
|
||||
static char recv_data_buf0[buf_len];
|
||||
static char recv_data_buf[buf_len];
|
||||
|
||||
char *recv_data_buf=recv_data_buf0; //fix strict alias warning
|
||||
// char *recv_data_buf=recv_data_buf0; //fix strict alias warning
|
||||
if(my_decrypt(input,recv_data_buf,input_len,key)!=0)
|
||||
{
|
||||
//printf("decrypt fail\n");
|
||||
@@ -793,15 +800,24 @@ int parse_safer(conn_info_t &conn_info,const char * input,int input_len,char &ty
|
||||
|
||||
|
||||
//char *a=recv_data_buf;
|
||||
id_t h_oppiste_id= ntohl ( *((id_t * )(recv_data_buf)) );
|
||||
//id_t h_oppiste_id= ntohl ( *((id_t * )(recv_data_buf)) );
|
||||
id_t h_oppsite_id;
|
||||
memcpy(&h_oppsite_id,recv_data_buf,sizeof(h_oppsite_id));
|
||||
h_oppsite_id=ntohl(h_oppsite_id);
|
||||
|
||||
id_t h_my_id= ntohl ( *((id_t * )(recv_data_buf+sizeof(id_t))) );
|
||||
//id_t h_my_id= ntohl ( *((id_t * )(recv_data_buf+sizeof(id_t))) );
|
||||
id_t h_my_id;
|
||||
memcpy(&h_my_id,recv_data_buf+sizeof(id_t),sizeof(h_my_id));
|
||||
h_my_id=ntohl(h_my_id);
|
||||
|
||||
anti_replay_seq_t h_seq= ntoh64 ( *((anti_replay_seq_t * )(recv_data_buf +sizeof(id_t) *2 )) );
|
||||
//anti_replay_seq_t h_seq= ntoh64 ( *((anti_replay_seq_t * )(recv_data_buf +sizeof(id_t) *2 )) );
|
||||
anti_replay_seq_t h_seq;
|
||||
memcpy(&h_seq,recv_data_buf +sizeof(id_t) *2 ,sizeof(h_seq));
|
||||
h_seq=ntoh64(h_seq);
|
||||
|
||||
if(h_oppiste_id!=conn_info.oppsite_id||h_my_id!=conn_info.my_id)
|
||||
if(h_oppsite_id!=conn_info.oppsite_id||h_my_id!=conn_info.my_id)
|
||||
{
|
||||
mylog(log_debug,"id and oppsite_id verification failed %x %x %x %x \n",h_oppiste_id,conn_info.oppsite_id,h_my_id,conn_info.my_id);
|
||||
mylog(log_debug,"id and oppsite_id verification failed %x %x %x %x \n",h_oppsite_id,conn_info.oppsite_id,h_my_id,conn_info.my_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -846,7 +862,7 @@ int parse_safer(conn_info_t &conn_info,const char * input,int input_len,char &ty
|
||||
|
||||
return 0;
|
||||
}
|
||||
int recv_safer(conn_info_t &conn_info,char &type,char* &data,int &len)
|
||||
int recv_safer(conn_info_t &conn_info,char &type,char* &data,int &len)///safer transfer function with anti-replay,when mutually verification is done.
|
||||
{
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
@@ -859,7 +875,7 @@ int recv_safer(conn_info_t &conn_info,char &type,char* &data,int &len)
|
||||
return parse_safer(conn_info,recv_data,recv_len,type,data,len);
|
||||
}
|
||||
|
||||
int try_to_list_and_bind(int port)
|
||||
int try_to_list_and_bind(int port) //try to bind to a port,may fail.
|
||||
{
|
||||
int old_bind_fd=bind_fd;
|
||||
|
||||
@@ -898,7 +914,7 @@ int try_to_list_and_bind(int port)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int client_bind_to_a_new_port()
|
||||
int client_bind_to_a_new_port()//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
|
||||
@@ -915,7 +931,7 @@ int client_bind_to_a_new_port()
|
||||
|
||||
|
||||
|
||||
int set_timer(int epollfd,int &timer_fd)
|
||||
int set_timer(int epollfd,int &timer_fd)//put a timer_fd into epoll,general function,used both in client and server
|
||||
{
|
||||
int ret;
|
||||
epoll_event ev;
|
||||
@@ -946,7 +962,7 @@ 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)//only for server
|
||||
{
|
||||
int ret;
|
||||
epoll_event ev;
|
||||
@@ -976,7 +992,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
|
||||
int client_on_timer(conn_info_t &conn_info) //for client. called when a timer is ready in epoll
|
||||
{
|
||||
//keep_iptables_rule();
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
@@ -1106,9 +1122,9 @@ int client_on_timer(conn_info_t &conn_info) //for client
|
||||
send_info.seq++;
|
||||
send_info.ack_seq=recv_info.seq+1;
|
||||
send_info.ts_ack=recv_info.ts;
|
||||
raw_info.reserved_seq=send_info.seq;
|
||||
raw_info.reserved_send_seq=send_info.seq;
|
||||
}
|
||||
send_info.seq=raw_info.reserved_seq;
|
||||
send_info.seq=raw_info.reserved_send_seq;
|
||||
send_info.psh = 0;
|
||||
send_info.syn = 0;
|
||||
send_info.ack = 1;
|
||||
@@ -1116,7 +1132,7 @@ int client_on_timer(conn_info_t &conn_info) //for client
|
||||
|
||||
send_handshake(raw_info,conn_info.my_id,0,const_id);
|
||||
|
||||
send_info.seq+=raw_info.last_send_len;
|
||||
send_info.seq+=raw_info.send_info.data_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1150,13 +1166,13 @@ int client_on_timer(conn_info_t &conn_info) //for client
|
||||
{
|
||||
if(conn_info.last_hb_sent_time==0)
|
||||
{
|
||||
send_info.ack_seq=recv_info.seq+raw_info.last_recv_len;
|
||||
send_info.ack_seq=recv_info.seq+raw_info.recv_info.data_len;
|
||||
send_info.ts_ack=recv_info.ts;
|
||||
raw_info.reserved_seq=send_info.seq;
|
||||
raw_info.reserved_send_seq=send_info.seq;
|
||||
}
|
||||
send_info.seq=raw_info.reserved_seq;
|
||||
send_info.seq=raw_info.reserved_send_seq;
|
||||
send_handshake(raw_info,conn_info.my_id,conn_info.oppsite_id,const_id);
|
||||
send_info.seq+=raw_info.last_send_len;
|
||||
send_info.seq+=raw_info.send_info.data_len;
|
||||
|
||||
}
|
||||
else
|
||||
@@ -1216,7 +1232,8 @@ int client_on_timer(conn_info_t &conn_info) //for client
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int server_on_timer_multi(conn_info_t &conn_info,char * ip_port)
|
||||
int server_on_timer_multi(conn_info_t &conn_info,char * ip_port) //for server. called when a timer is ready in epoll.for server,there will be one timer for every connection
|
||||
|
||||
{
|
||||
//keep_iptables_rule();
|
||||
mylog(log_trace,"server timer!\n");
|
||||
@@ -1260,7 +1277,7 @@ int server_on_timer_multi(conn_info_t &conn_info,char * ip_port)
|
||||
return 0;
|
||||
|
||||
}
|
||||
int client_on_raw_recv(conn_info_t &conn_info)
|
||||
int client_on_raw_recv(conn_info_t &conn_info) //called when raw fd received a packet.
|
||||
{
|
||||
char* data;int data_len;
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
@@ -1324,9 +1341,20 @@ int client_on_raw_recv(conn_info_t &conn_info)
|
||||
mylog(log_debug,"too short to be a handshake\n");
|
||||
return -1;
|
||||
}
|
||||
id_t tmp_oppsite_id= ntohl(* ((u32_t *)&data[0]));
|
||||
id_t tmp_my_id=ntohl(* ((u32_t *)&data[sizeof(id_t)]));
|
||||
id_t tmp_oppsite_const_id=ntohl(* ((u32_t *)&data[sizeof(id_t)*2]));
|
||||
//id_t tmp_oppsite_id= ntohl(* ((u32_t *)&data[0]));
|
||||
id_t tmp_oppsite_id;
|
||||
memcpy(&tmp_oppsite_id,&data[0],sizeof(tmp_oppsite_id));
|
||||
tmp_oppsite_id=ntohl(tmp_oppsite_id);
|
||||
|
||||
//id_t tmp_my_id=ntohl(* ((u32_t *)&data[sizeof(id_t)]));
|
||||
id_t tmp_my_id;
|
||||
memcpy(&tmp_my_id,&data[sizeof(id_t)],sizeof(tmp_my_id));
|
||||
tmp_my_id=ntohl(tmp_my_id);
|
||||
|
||||
//id_t tmp_oppsite_const_id=ntohl(* ((u32_t *)&data[sizeof(id_t)*2]));
|
||||
id_t tmp_oppsite_const_id;
|
||||
memcpy(&tmp_oppsite_const_id,&data[sizeof(id_t)*2],sizeof(tmp_oppsite_const_id));
|
||||
tmp_oppsite_const_id=ntohl(tmp_oppsite_const_id);
|
||||
|
||||
if(tmp_my_id!=conn_info.my_id)
|
||||
{
|
||||
@@ -1394,7 +1422,10 @@ int client_on_raw_recv(conn_info_t &conn_info)
|
||||
|
||||
conn_info.last_hb_recv_time=get_current_time();
|
||||
|
||||
u32_t tmp_conv_id= ntohl(* ((u32_t *)&data[0]));
|
||||
//u32_t tmp_conv_id= ntohl(* ((u32_t *)&data[0]));
|
||||
u32_t tmp_conv_id;
|
||||
memcpy(&tmp_conv_id,&data[0],sizeof(tmp_conv_id));
|
||||
tmp_conv_id=ntohl(tmp_conv_id);
|
||||
|
||||
if(!conn_info.blob->conv_manager.is_conv_used(tmp_conv_id))
|
||||
{
|
||||
@@ -1440,7 +1471,7 @@ int client_on_raw_recv(conn_info_t &conn_info)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int handle_lower_level(raw_info_t &raw_info)
|
||||
int handle_lower_level(raw_info_t &raw_info)//fill lower_level info,when --lower-level is enabled,only for server
|
||||
{
|
||||
packet_info_t &send_info=raw_info.send_info;
|
||||
packet_info_t &recv_info=raw_info.recv_info;
|
||||
@@ -1469,7 +1500,7 @@ int handle_lower_level(raw_info_t &raw_info)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int server_on_raw_recv_multi()
|
||||
int server_on_raw_recv_multi() //called when server received an raw packet
|
||||
{
|
||||
char dummy_buf[buf_len];
|
||||
packet_info_t peek_info;
|
||||
@@ -1531,6 +1562,10 @@ int server_on_raw_recv_multi()
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
recv(raw_recv_fd, 0,0,0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(!conn_manager.exist(ip,port))
|
||||
@@ -1559,7 +1594,11 @@ int server_on_raw_recv_multi()
|
||||
return -1;
|
||||
}
|
||||
|
||||
id_t zero=ntohl(* ((u32_t *)&data[sizeof(id_t)]));
|
||||
//id_t zero=ntohl(* ((u32_t *)&data[sizeof(id_t)]));
|
||||
id_t zero;
|
||||
memcpy(&zero,&data[sizeof(id_t)],sizeof(zero));
|
||||
zero=ntohl(zero);
|
||||
|
||||
if(zero!=0)
|
||||
{
|
||||
mylog(log_debug,"[%s]not a invalid initial handshake\n",ip_port);
|
||||
@@ -1613,7 +1652,7 @@ int server_on_raw_recv_multi()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
server_on_raw_recv_handshake1(conn_info,ip_port,data,data_len);
|
||||
return server_on_raw_recv_handshake1(conn_info,ip_port,data,data_len);
|
||||
}
|
||||
if(conn_info.state.server_current_state==server_ready)
|
||||
{
|
||||
@@ -1625,7 +1664,15 @@ int server_on_raw_recv_multi()
|
||||
//mylog(log_info,"after recv_safer\n");
|
||||
return server_on_raw_recv_ready(conn_info,ip_port,type,data,data_len);
|
||||
}
|
||||
return 0;
|
||||
|
||||
if(conn_info.state.server_current_state==server_idle)
|
||||
{
|
||||
recv(raw_recv_fd, 0,0, 0 );//
|
||||
return 0;
|
||||
}
|
||||
mylog(log_fatal,"we should never run to here\n");
|
||||
myexit(-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1639,7 +1686,7 @@ int server_on_raw_recv_handshake1(conn_info_t &conn_info,id_t tmp_oppsite_id )
|
||||
|
||||
return 0;
|
||||
}*/
|
||||
int server_on_raw_recv_handshake1(conn_info_t &conn_info,char * ip_port,char * data, int data_len)
|
||||
int server_on_raw_recv_handshake1(conn_info_t &conn_info,char * ip_port,char * data, int data_len)//called when server received a handshake1 packet from client
|
||||
{
|
||||
packet_info_t &send_info=conn_info.raw_info.send_info;
|
||||
packet_info_t &recv_info=conn_info.raw_info.recv_info;
|
||||
@@ -1656,15 +1703,22 @@ int server_on_raw_recv_handshake1(conn_info_t &conn_info,char * ip_port,char * d
|
||||
mylog(log_debug,"[%s] data_len=%d too short to be a handshake\n",ip_port,data_len);
|
||||
return -1;
|
||||
}
|
||||
id_t tmp_oppsite_id= ntohl(* ((u32_t *)&data[0]));
|
||||
id_t tmp_my_id=ntohl(* ((u32_t *)&data[sizeof(id_t)]));
|
||||
//id_t tmp_oppsite_id= ntohl(* ((u32_t *)&data[0]));
|
||||
id_t tmp_oppsite_id;
|
||||
memcpy(&tmp_oppsite_id,(u32_t *)&data[0],sizeof(tmp_oppsite_id));
|
||||
tmp_oppsite_id=ntohl(tmp_oppsite_id);
|
||||
|
||||
//id_t tmp_my_id=ntohl(* ((u32_t *)&data[sizeof(id_t)]));
|
||||
id_t tmp_my_id;
|
||||
memcpy(&tmp_my_id,&data[sizeof(id_t)],sizeof(tmp_my_id));
|
||||
tmp_my_id=ntohl(tmp_my_id);
|
||||
|
||||
if(tmp_my_id==0) //received init handshake again
|
||||
{
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
send_info.seq=recv_info.ack_seq;
|
||||
send_info.ack_seq=recv_info.seq+raw_info.last_recv_len;
|
||||
send_info.ack_seq=recv_info.seq+raw_info.recv_info.data_len;
|
||||
send_info.ts_ack=recv_info.ts;
|
||||
}
|
||||
if(raw_mode==mode_icmp)
|
||||
@@ -1678,12 +1732,17 @@ int server_on_raw_recv_handshake1(conn_info_t &conn_info,char * ip_port,char * d
|
||||
else if(tmp_my_id==conn_info.my_id)
|
||||
{
|
||||
conn_info.oppsite_id=tmp_oppsite_id;
|
||||
id_t tmp_oppsite_const_id=ntohl(* ((u32_t *)&data[sizeof(id_t)*2]));
|
||||
//id_t tmp_oppsite_const_id=ntohl(* ((u32_t *)&data[sizeof(id_t)*2]));
|
||||
|
||||
id_t tmp_oppsite_const_id;
|
||||
memcpy(&tmp_oppsite_const_id,&data[sizeof(id_t)*2],sizeof(tmp_oppsite_const_id));
|
||||
tmp_oppsite_const_id=ntohl(tmp_oppsite_const_id);
|
||||
|
||||
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
send_info.seq=recv_info.ack_seq;
|
||||
send_info.ack_seq=recv_info.seq+raw_info.last_recv_len;
|
||||
send_info.ack_seq=recv_info.seq+raw_info.recv_info.data_len;
|
||||
send_info.ts_ack=recv_info.ts;
|
||||
}
|
||||
|
||||
@@ -1701,7 +1760,8 @@ int server_on_raw_recv_handshake1(conn_info_t &conn_info,char * ip_port,char * d
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,char *data,int data_len)
|
||||
int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,char *data,int data_len) //called while the state for a connection is server_ready
|
||||
//receives data and heart beat by recv_safer.
|
||||
{
|
||||
|
||||
raw_info_t &raw_info = conn_info.raw_info;
|
||||
@@ -1727,7 +1787,11 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
|
||||
} else if (type== 'd' && data_len >=int( sizeof(u32_t) ))
|
||||
{
|
||||
|
||||
u32_t tmp_conv_id = ntohl(*((u32_t *) &data[0]));
|
||||
//u32_t tmp_conv_id = ntohl(*((u32_t *) &data[0]));
|
||||
id_t tmp_conv_id;
|
||||
memcpy(&tmp_conv_id,&data[0],sizeof(tmp_conv_id));
|
||||
tmp_conv_id=ntohl(tmp_conv_id);
|
||||
|
||||
|
||||
conn_info.last_hb_recv_time = get_current_time();
|
||||
|
||||
@@ -1813,7 +1877,8 @@ int server_on_raw_recv_ready(conn_info_t &conn_info,char * ip_port,char type,cha
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_pre_ready(conn_info_t &conn_info,char * ip_port,u32_t tmp_oppsite_const_id)// do prepare work before state change to server ready for a specifc connection
|
||||
//connection recovery is also handle here
|
||||
{
|
||||
//u32_t ip;uint16_t port;
|
||||
//ip=conn_info.raw_info.recv_info.src_ip;
|
||||
@@ -1931,7 +1996,7 @@ int server_on_raw_recv_pre_ready(conn_info_t &conn_info,char * ip_port,u32_t tmp
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_src_adress(u32_t &ip)
|
||||
int get_src_adress(u32_t &ip) //a trick to get src adress for a dest adress,so that we can use the src address in raw socket as source ip
|
||||
{
|
||||
struct sockaddr_in remote_addr_in={0};
|
||||
|
||||
@@ -2497,7 +2562,7 @@ int server_event_loop()
|
||||
return 0;
|
||||
}
|
||||
//char lower_level_arg[1000];
|
||||
int process_lower_level_arg()
|
||||
int process_lower_level_arg()//handle --lower-level option
|
||||
{
|
||||
lower_level=1;
|
||||
if(strcmp(optarg,"auto")==0)
|
||||
@@ -2527,8 +2592,12 @@ int process_lower_level_arg()
|
||||
}
|
||||
void print_help()
|
||||
{
|
||||
char git_version_buf[100]={0};
|
||||
strncpy(git_version_buf,gitversion,10);
|
||||
printf("udp2raw-tunnel\n");
|
||||
printf("version: %s %s\n",__DATE__,__TIME__);
|
||||
printf("git version:%s ",git_version_buf);
|
||||
printf("build date:%s %s\n",__DATE__,__TIME__);
|
||||
|
||||
printf("repository: https://github.com/wangyu-/udp2raw-tunnel\n");
|
||||
printf("\n");
|
||||
printf("usage:\n");
|
||||
@@ -2552,7 +2621,8 @@ void print_help()
|
||||
printf(" this option disables port changing while re-connecting\n");
|
||||
// printf(" \n");
|
||||
printf("other options:\n");
|
||||
printf(" --conf-file <string> read options from a configuration file instead of command line\n");
|
||||
printf(" --conf-file <string> read options from a configuration file instead of command line.\n");
|
||||
printf(" check example.conf in repo for format\n");
|
||||
printf(" --log-level <number> 0:never 1:fatal 2:error 3:warn \n");
|
||||
printf(" 4:info (default) 5:debug 6:trace\n");
|
||||
// printf("\n");
|
||||
@@ -2562,22 +2632,27 @@ void print_help()
|
||||
printf(" unless you suspect there is a bug\n");
|
||||
// printf("\n");
|
||||
printf(" --sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024\n");
|
||||
printf(" --seqmode <number> seq increase mode for faketcp:\n");
|
||||
printf(" 0:dont increase\n");
|
||||
printf(" 1:increase every packet(default)\n");
|
||||
printf(" 2:increase randomly, about every 3 packets\n");
|
||||
printf(" --force-sock-buf bypass system limitation while setting sock-buf\n");
|
||||
printf(" --seq-mode <number> seq increase mode for faketcp:\n");
|
||||
printf(" 0:static header,do not increase seq and ack_seq\n");
|
||||
printf(" 1:increase seq for every packet,simply ack last seq\n");
|
||||
printf(" 2:increase seq randomly, about every 3 packets,simply ack last seq\n");
|
||||
printf(" 3:simulate an almost real seq/ack procedure(default)\n");
|
||||
printf(" 4:similiar to 3,but do not consider TCP Option Window_Scale,\n");
|
||||
printf(" maybe useful when firewall doesnt support TCP Option \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(" --gen-add generate iptables rule and add it for you,then exit.overrides -g\n");
|
||||
printf(" --keep_rule monitor iptables and auto re-add if necessary.Implys -a\n");
|
||||
printf(" --lower-level <string> send packets at OSI level 2, format:'if_name#dest_mac_adress'\n");
|
||||
printf(" ie:'eth0#00:23:45:67:89:b9'.or try '--lower-level auto' to obtain\n");
|
||||
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(" --clear clear any iptables rules added by this program.overrides everything\n");
|
||||
printf(" -h,--help print this help message\n");
|
||||
|
||||
//printf("common options,these options must be same on both side\n");
|
||||
}
|
||||
|
||||
int load_config(char *file_name, int &argc, vector<string> &argv)
|
||||
int load_config(char *file_name, int &argc, vector<string> &argv) //load conf file and append to argv
|
||||
{
|
||||
// Load configurations from config_file instead of the command line.
|
||||
// See config.example for example configurations
|
||||
@@ -2602,6 +2677,7 @@ int load_config(char *file_name, int &argc, vector<string> &argv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unit_test()
|
||||
{
|
||||
printf("running unit test\n");
|
||||
@@ -2617,10 +2693,50 @@ int unit_test()
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
char s1[]={1,2,3,4,5};
|
||||
|
||||
char s2[]={1};
|
||||
|
||||
short c1=csum((unsigned short*)s1,5);
|
||||
short c2=csum((unsigned short*)s2,1);
|
||||
//c2=0;
|
||||
|
||||
printf("%x %x\n",(int)c1,(int)c2);
|
||||
|
||||
const char buf[]={1,2,3,4,5,6,7,8,9,10,11,2,13,14,15,16};
|
||||
char key[100]={0};
|
||||
char buf2[100]={0};
|
||||
char buf3[100]={0};
|
||||
char buf4[100]={0};
|
||||
int len=16;
|
||||
for(int i=0;i<len;i++)
|
||||
{
|
||||
printf("<%d>",buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
cipher_encrypt(buf,buf2,len,key);
|
||||
for(int i=0;i<len;i++)
|
||||
{
|
||||
printf("<%d>",buf2[i]);
|
||||
}
|
||||
printf("\n");
|
||||
int temp_len=len;
|
||||
cipher_decrypt(buf2,buf3,len,key);
|
||||
for(int i=0;i<len;i++)
|
||||
{
|
||||
printf("<%d>",buf3[i]);
|
||||
}
|
||||
printf("\n");
|
||||
cipher_encrypt(buf2,buf4,temp_len,key);
|
||||
for(int i=0;i<temp_len;i++)
|
||||
{
|
||||
printf("<%d>",buf4[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int process_log_level(int argc,char *argv[])
|
||||
int process_log_level(int argc,char *argv[])//process --log-level and --disable-cloer --log-postion options
|
||||
{
|
||||
int i,j,k;
|
||||
for (i = 0; i < argc; i++)
|
||||
@@ -2651,7 +2767,7 @@ int process_log_level(int argc,char *argv[])
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void process_arg(int argc, char *argv[])
|
||||
void process_arg(int argc, char *argv[]) //process all options
|
||||
{
|
||||
int i,j,k,opt;
|
||||
|
||||
@@ -2683,6 +2799,7 @@ void process_arg(int argc, char *argv[])
|
||||
{"sock-buf", required_argument, 0, 1},
|
||||
{"seq-mode", required_argument, 0, 1},
|
||||
{"conf-file", required_argument, 0, 1},
|
||||
{"force-sock-buf", no_argument, 0, 1},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -2967,6 +3084,10 @@ void process_arg(int argc, char *argv[])
|
||||
{
|
||||
//enable_log_position=1;
|
||||
}
|
||||
else if(strcmp(long_options[option_index].name,"force-sock-buf")==0)
|
||||
{
|
||||
force_socket_buf=1;
|
||||
}
|
||||
else if(strcmp(long_options[option_index].name,"disable-bpf")==0)
|
||||
{
|
||||
disable_bpf_filter=1;
|
||||
@@ -2992,7 +3113,7 @@ void process_arg(int argc, char *argv[])
|
||||
else if(strcmp(long_options[option_index].name,"seq-mode")==0)
|
||||
{
|
||||
sscanf(optarg,"%d",&seq_mode);
|
||||
if(0<=seq_mode&&seq_mode<=2)
|
||||
if(0<=seq_mode&&seq_mode<=max_seq_mode)
|
||||
{
|
||||
}
|
||||
else
|
||||
@@ -3050,7 +3171,7 @@ void process_arg(int argc, char *argv[])
|
||||
|
||||
log_bare(log_info,"\n");
|
||||
}
|
||||
void pre_process_arg(int argc, char *argv[])
|
||||
void pre_process_arg(int argc, char *argv[])//mainly for load conf file
|
||||
{
|
||||
int i,j,k;
|
||||
for (i = 0; i < argc; i++)
|
||||
@@ -3137,12 +3258,12 @@ void pre_process_arg(int argc, char *argv[])
|
||||
process_arg(new_argc,new_argv_char);
|
||||
|
||||
}
|
||||
void *run_keep(void *none)
|
||||
void *run_keep(void *none) //called in a new thread for --keep-rule option
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
sleep(10);
|
||||
sleep(iptables_rule_keep_interval);
|
||||
keep_iptables_rule();
|
||||
if(about_to_exit) //just incase it runs forever if there is some bug,not necessary
|
||||
{
|
||||
@@ -3154,7 +3275,7 @@ void *run_keep(void *none)
|
||||
return NULL;
|
||||
|
||||
}
|
||||
void iptables_rule()
|
||||
void iptables_rule() // handles -a -g --gen-add --keep-rule
|
||||
{
|
||||
if(auto_add_iptables_rule&&generate_iptables_rule)
|
||||
{
|
||||
@@ -3258,7 +3379,7 @@ void iptables_rule()
|
||||
}
|
||||
if(generate_iptables_rule)
|
||||
{
|
||||
string rule="iptables -I ";
|
||||
string rule="iptables -I INPUT ";
|
||||
rule+=pattern;
|
||||
rule+=" -j DROP";
|
||||
|
||||
@@ -3292,7 +3413,7 @@ int test()
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
//test();
|
||||
printf("%s\n",my_ntoa(0x00ffffff));
|
||||
//printf("%s\n",my_ntoa(0x00ffffff));
|
||||
//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));
|
||||
|
55
makefile
55
makefile
@@ -1,59 +1,68 @@
|
||||
cc_cross=/home/wangyu/Desktop/arm-2014.05/bin/arm-none-linux-gnueabi-g++
|
||||
cc_local=g++
|
||||
cc_mips34kc=/toolchains/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_mips34kc=/toolchains/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_mips24kc_be=/toolchains/lede-sdk-17.01.2-ar71xx-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/bin/mips-openwrt-linux-musl-g++
|
||||
cc_mips24kc_le=/toolchains/lede-sdk-17.01.2-ramips-mt7621_gcc-5.4.0_musl-1.1.16.Linux-x86_64/staging_dir/toolchain-mipsel_24kc_gcc-5.4.0_musl-1.1.16/bin/mipsel-openwrt-linux-musl-g++
|
||||
#cc_arm= /toolchains/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-g++ -march=armv6 -marm
|
||||
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
|
||||
|
||||
SOURCES=main.cpp lib/aes.c lib/md5.c encrypt.cpp log.cpp network.cpp common.cpp -lpthread
|
||||
SOURCES_AES_ACC=$(filter-out lib/aes.c,$(SOURCES)) $(wildcard lib/aes_acc/aes*.c)
|
||||
COMMON=main.cpp lib/md5.c encrypt.cpp log.cpp network.cpp common.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 mips34kc arm amd64_hw_aes arm_asm_aes mips34kc_asm_aes x86 x86_asm_aes
|
||||
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'`
|
||||
|
||||
all:
|
||||
all:git_version
|
||||
rm -f ${NAME}
|
||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -ggdb -static -O3
|
||||
fast:
|
||||
fast: git_version
|
||||
rm -f ${NAME}
|
||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -ggdb
|
||||
debug:
|
||||
debug: git_version
|
||||
rm -f ${NAME}
|
||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -D MY_DEBUG
|
||||
debug2:
|
||||
debug2: git_version
|
||||
rm -f ${NAME}
|
||||
${cc_local} -o ${NAME} -I. ${SOURCES} ${FLAGS} -lrt -Wformat-nonliteral -ggdb
|
||||
|
||||
mips34kc:
|
||||
${cc_mips34kc} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
|
||||
mips24kc_be: git_version
|
||||
${cc_mips24kc_be} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
|
||||
mips24kc_be_asm_aes: git_version
|
||||
${cc_mips24kc_be} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -lgcc_eh -static -O3 lib/aes_acc/asm/mips_be.S
|
||||
|
||||
mips34kc_asm_aes:
|
||||
${cc_mips34kc} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -lgcc_eh -static -O3 lib/aes_acc/asm/mips_be.S
|
||||
mips24kc_le: git_version
|
||||
${cc_mips24kc_le} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -lgcc_eh -static -O3
|
||||
mips24kc_le_asm_aes: git_version
|
||||
${cc_mips24kc_le} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -lgcc_eh -static -O3 lib/aes_acc/asm/mips.S
|
||||
|
||||
#bcm2708:
|
||||
# ${cc_bcm2708} -o ${NAME}_bcm2708 -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
amd64:
|
||||
amd64:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
amd64_hw_aes:
|
||||
amd64_hw_aes:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/x64.S
|
||||
x86:
|
||||
x86:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3 -m32
|
||||
x86_asm_aes:
|
||||
x86_asm_aes:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 -m32 lib/aes_acc/asm/x86.S
|
||||
arm:
|
||||
arm:git_version
|
||||
${cc_arm} -o ${NAME}_$@ -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
|
||||
arm_asm_aes:
|
||||
arm_asm_aes:git_version
|
||||
${cc_arm} -o ${NAME}_$@ -I. ${SOURCES_AES_ACC} ${FLAGS} -lrt -static -O3 lib/aes_acc/asm/arm.S
|
||||
|
||||
cross:
|
||||
cross:git_version
|
||||
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -O3
|
||||
|
||||
cross2:
|
||||
cross2:git_version
|
||||
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -lgcc_eh -O3
|
||||
|
||||
cross3:
|
||||
cross3:git_version
|
||||
${cc_cross} -o ${NAME}_cross -I. ${SOURCES} ${FLAGS} -lrt -static -O3
|
||||
|
||||
release: ${TARGETS}
|
||||
@@ -62,4 +71,8 @@ release: ${TARGETS}
|
||||
clean:
|
||||
rm -f ${TAR}
|
||||
rm -f udp2raw udp2raw_cross udp2raw_cmake
|
||||
rm -f git_version.h
|
||||
|
||||
git_version:
|
||||
echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > git_version.h
|
||||
|
||||
|
168
network.cpp
168
network.cpp
@@ -12,7 +12,8 @@ int raw_recv_fd=-1;
|
||||
int raw_send_fd=-1;
|
||||
u32_t link_level_header_len=0;//set it to 14 if SOCK_RAW is used in socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
|
||||
|
||||
int seq_mode=1;
|
||||
int seq_mode=3;
|
||||
int max_seq_mode=4;
|
||||
|
||||
int filter_port=-1;
|
||||
|
||||
@@ -31,6 +32,10 @@ unsigned char dest_hw_addr[sizeof(sockaddr_ll::sll_addr)]=
|
||||
{0xff,0xff,0xff,0xff,0xff,0xff,0,0};
|
||||
//{0x00,0x23,0x45,0x67,0x89,0xb9};
|
||||
|
||||
const u32_t receive_window_lower_bound=40960;
|
||||
const u32_t receive_window_random_range=512;
|
||||
const unsigned char wscale=0x05;
|
||||
|
||||
struct sock_filter code_tcp_old[] = {
|
||||
{ 0x28, 0, 0, 0x0000000c },//0
|
||||
{ 0x15, 0, 10, 0x00000800 },//1
|
||||
@@ -146,6 +151,7 @@ packet_info_t::packet_info_t()
|
||||
ts_ack=0;
|
||||
syn=0;
|
||||
ack=1;
|
||||
ack_seq_counter=0;
|
||||
|
||||
//mylog(log_info,"<cons ,ts_ack= %u>\n",ts_ack);
|
||||
}
|
||||
@@ -199,11 +205,22 @@ int init_raw_socket()
|
||||
|
||||
}
|
||||
|
||||
if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_SNDBUFFORCE fail\n");
|
||||
myexit(1);
|
||||
}
|
||||
if(force_socket_buf)
|
||||
{
|
||||
if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_SNDBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||
myexit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(setsockopt(raw_send_fd, SOL_SOCKET, SO_SNDBUF, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_SNDBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||
myexit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -217,11 +234,22 @@ int init_raw_socket()
|
||||
myexit(1);
|
||||
}
|
||||
|
||||
if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_RCVBUFFORCE fail\n");
|
||||
myexit(1);
|
||||
}
|
||||
if(force_socket_buf)
|
||||
{
|
||||
if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUFFORCE, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_RCVBUFFORCE fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||
myexit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(setsockopt(raw_recv_fd, SOL_SOCKET, SO_RCVBUF, &socket_buf_size, sizeof(socket_buf_size))<0)
|
||||
{
|
||||
mylog(log_fatal,"SO_RCVBUF fail socket_buf_size=%d errno=%s\n",socket_buf_size,strerror(errno));
|
||||
myexit(1);
|
||||
}
|
||||
}
|
||||
|
||||
//IP_HDRINCL to tell the kernel that headers are included in the packet
|
||||
|
||||
@@ -844,8 +872,8 @@ int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen) {
|
||||
|
||||
//mylog(log_debug,"syn %d\n",send_info.syn);
|
||||
|
||||
char send_raw_tcp_buf0[buf_len];
|
||||
char *send_raw_tcp_buf=send_raw_tcp_buf0;
|
||||
char send_raw_tcp_buf[buf_len];
|
||||
//char *send_raw_tcp_buf=send_raw_tcp_buf0;
|
||||
|
||||
struct tcphdr *tcph = (struct tcphdr *) (send_raw_tcp_buf
|
||||
+ sizeof(struct pseudo_header));
|
||||
@@ -884,20 +912,26 @@ int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen) {
|
||||
send_raw_tcp_buf[i++] = 0x08; //ts i=6
|
||||
send_raw_tcp_buf[i++] = 0x0a; //i=7
|
||||
|
||||
*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(
|
||||
(u32_t) get_current_time());
|
||||
//*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(
|
||||
// (u32_t) get_current_time());
|
||||
|
||||
u32_t ts=htonl((u32_t) get_current_time());
|
||||
memcpy(&send_raw_tcp_buf[i],&ts,sizeof(ts));
|
||||
|
||||
i += 4;
|
||||
|
||||
//mylog(log_info,"[syn]<send_info.ts_ack= %u>\n",send_info.ts_ack);
|
||||
|
||||
*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack);
|
||||
//*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack);
|
||||
u32_t ts_ack=htonl(send_info.ts_ack);
|
||||
memcpy(&send_raw_tcp_buf[i],&ts_ack,sizeof(ts_ack));
|
||||
|
||||
i += 4;
|
||||
|
||||
send_raw_tcp_buf[i++] = 0x01;
|
||||
send_raw_tcp_buf[i++] = 0x03;
|
||||
send_raw_tcp_buf[i++] = 0x03;
|
||||
send_raw_tcp_buf[i++] = 0x05;
|
||||
send_raw_tcp_buf[i++] = wscale;
|
||||
} else {
|
||||
tcph->doff = 8;
|
||||
int i = sizeof(pseudo_header)+sizeof(tcphdr);
|
||||
@@ -908,20 +942,25 @@ int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen) {
|
||||
send_raw_tcp_buf[i++] = 0x08; //ts //i=2
|
||||
send_raw_tcp_buf[i++] = 0x0a; //i=3;
|
||||
|
||||
*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(
|
||||
(u32_t) get_current_time());
|
||||
//*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(
|
||||
// (u32_t) get_current_time());
|
||||
|
||||
u32_t ts=htonl((u32_t) get_current_time());
|
||||
memcpy(&send_raw_tcp_buf[i],&ts,sizeof(ts));
|
||||
|
||||
i += 4;
|
||||
|
||||
//mylog(log_info,"<send_info.ts_ack= %u>\n",send_info.ts_ack);
|
||||
|
||||
*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack);
|
||||
//*(u32_t*) (&send_raw_tcp_buf[i]) = htonl(send_info.ts_ack);
|
||||
u32_t ts_ack=htonl(send_info.ts_ack);
|
||||
memcpy(&send_raw_tcp_buf[i],&ts_ack,sizeof(ts_ack));
|
||||
i += 4;
|
||||
}
|
||||
|
||||
tcph->urg = 0;
|
||||
//tcph->window = htons((uint16_t)(1024));
|
||||
tcph->window = htons((uint16_t) (10240 + random() % 100));
|
||||
tcph->window = htons((uint16_t) (receive_window_lower_bound + random() % receive_window_random_range));
|
||||
|
||||
tcph->check = 0; //leave checksum 0 now, filled later by pseudo header
|
||||
tcph->urg_ptr = 0;
|
||||
@@ -948,7 +987,7 @@ int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen) {
|
||||
}
|
||||
|
||||
|
||||
raw_info.last_send_len=payloadlen;
|
||||
raw_info.send_info.data_len=payloadlen;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
@@ -1334,8 +1373,14 @@ int recv_raw_tcp(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
||||
if(tcp_option[6]==0x08 &&tcp_option[7]==0x0a)
|
||||
{
|
||||
recv_info.has_ts=1;
|
||||
recv_info.ts=ntohl(*(u32_t*)(&tcp_option[8]));
|
||||
recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[12]));
|
||||
//recv_info.ts=ntohl(*(u32_t*)(&tcp_option[8]));
|
||||
memcpy(&recv_info.ts,&tcp_option[8],sizeof(recv_info.ts));
|
||||
recv_info.ts=ntohl(recv_info.ts);
|
||||
|
||||
//recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[12]));
|
||||
memcpy(&recv_info.ts_ack,&tcp_option[12],sizeof(recv_info.ts_ack));
|
||||
recv_info.ts_ack=ntohl(recv_info.ts_ack);
|
||||
|
||||
//g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[8]));
|
||||
}
|
||||
else
|
||||
@@ -1348,8 +1393,12 @@ int recv_raw_tcp(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
||||
if(tcp_option[2]==0x08 &&tcp_option[3]==0x0a)
|
||||
{
|
||||
recv_info.has_ts=1;
|
||||
recv_info.ts=ntohl(*(u32_t*)(&tcp_option[4]));
|
||||
recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[8]));
|
||||
//recv_info.ts=ntohl(*(u32_t*)(&tcp_option[4]));
|
||||
memcpy(&recv_info.ts,&tcp_option[4],sizeof(recv_info.ts));
|
||||
recv_info.ts=ntohl(recv_info.ts);
|
||||
//recv_info.ts_ack=ntohl(*(u32_t*)(&tcp_option[8]));
|
||||
memcpy(&recv_info.ts_ack,&tcp_option[8],sizeof(recv_info.ts_ack));
|
||||
recv_info.ts_ack=ntohl(recv_info.ts_ack);
|
||||
//g_packet_info_send.ts_ack= ntohl(*(uint32_t*)(&tcp_option[0]));
|
||||
}
|
||||
else
|
||||
@@ -1370,7 +1419,20 @@ int recv_raw_tcp(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
||||
recv_info.dst_port=ntohs(tcph->dest);
|
||||
|
||||
recv_info.seq=ntohl(tcph->seq);
|
||||
|
||||
// recv_info.last_last_ack_seq=recv_info.last_ack_seq;
|
||||
//recv_info.last_ack_seq=recv_info.ack_seq;
|
||||
u32_t last_ack_seq=recv_info.ack_seq;
|
||||
recv_info.ack_seq=ntohl(tcph->ack_seq);
|
||||
if(recv_info.ack_seq==last_ack_seq)
|
||||
{
|
||||
recv_info.ack_seq_counter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
recv_info.ack_seq_counter=0;
|
||||
}
|
||||
|
||||
recv_info.psh=tcph->psh;
|
||||
|
||||
if(tcph->rst==1)
|
||||
@@ -1391,7 +1453,7 @@ int recv_raw_tcp(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
||||
{
|
||||
send_info.ack_seq=recv_info.seq;
|
||||
}*/
|
||||
raw_info.last_recv_len=payloadlen;
|
||||
raw_info.recv_info.data_len=payloadlen;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
@@ -1593,18 +1655,47 @@ int after_send_raw0(raw_info_t &raw_info)
|
||||
|
||||
if(raw_mode==mode_faketcp)
|
||||
{
|
||||
if (send_info.syn == 0 && send_info.ack == 1&& raw_info.last_send_len != 0) //only modify send_info when the packet is not part of handshake
|
||||
if (send_info.syn == 0 && send_info.ack == 1&& raw_info.send_info.data_len != 0) //only modify send_info when the packet is not part of handshake
|
||||
{
|
||||
if (seq_mode == 0)
|
||||
{
|
||||
|
||||
} else if (seq_mode == 1)
|
||||
{
|
||||
send_info.seq += raw_info.last_send_len; //////////////////modify
|
||||
send_info.seq += raw_info.send_info.data_len; //////////////////modify
|
||||
} else if (seq_mode == 2)
|
||||
{
|
||||
if (random() % 5 == 3)
|
||||
send_info.seq += raw_info.last_send_len; //////////////////modify
|
||||
send_info.seq += raw_info.send_info.data_len; //////////////////modify
|
||||
}
|
||||
else if(seq_mode==3||seq_mode==4)
|
||||
{
|
||||
send_info.seq += raw_info.send_info.data_len;
|
||||
|
||||
u32_t window_size;
|
||||
|
||||
if(seq_mode==3)
|
||||
{
|
||||
window_size=(u32_t)((u32_t)receive_window_lower_bound<<(u32_t)wscale);
|
||||
}
|
||||
else//seq_mode==4
|
||||
{
|
||||
window_size=(u32_t)((u32_t)receive_window_lower_bound);
|
||||
}
|
||||
|
||||
if(larger_than_u32(send_info.seq+max_data_len,recv_info.ack_seq+window_size))
|
||||
{
|
||||
send_info.seq=raw_info.recv_info.ack_seq;
|
||||
}
|
||||
if(recv_info.ack_seq_counter>=3) //simulate tcp fast re-transmit
|
||||
{
|
||||
recv_info.ack_seq_counter=0;
|
||||
send_info.seq=raw_info.recv_info.ack_seq;
|
||||
}
|
||||
if(larger_than_u32(raw_info.recv_info.ack_seq,send_info.seq)) //for further use,currently no effect.
|
||||
{
|
||||
send_info.seq=raw_info.recv_info.ack_seq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1626,10 +1717,21 @@ int after_recv_raw0(raw_info_t &raw_info)
|
||||
{
|
||||
if(recv_info.has_ts)
|
||||
send_info.ts_ack=recv_info.ts;
|
||||
if (recv_info.syn == 0 && recv_info.ack == 1 && raw_info.last_recv_len != 0) //only modify send_info when the packet is not part of handshake
|
||||
if (recv_info.syn == 0 && recv_info.ack == 1 && raw_info.recv_info.data_len != 0) //only modify send_info when the packet is not part of handshake
|
||||
{
|
||||
if(larger_than_u32(recv_info.seq+raw_info.last_recv_len,send_info.ack_seq))
|
||||
send_info.ack_seq = recv_info.seq+raw_info.last_recv_len;//TODO only update if its larger
|
||||
if(seq_mode==0||seq_mode==1||seq_mode==2)
|
||||
{
|
||||
if(larger_than_u32(recv_info.seq+raw_info.recv_info.data_len,send_info.ack_seq))
|
||||
send_info.ack_seq = recv_info.seq+raw_info.recv_info.data_len;//TODO only update if its larger
|
||||
}
|
||||
else if(seq_mode==3||seq_mode==4)
|
||||
{
|
||||
if(recv_info.seq==send_info.ack_seq)
|
||||
{
|
||||
send_info.ack_seq=recv_info.seq+raw_info.recv_info.data_len;//currently we dont remembr tcp segments,this is the simplest way
|
||||
//TODO implement tcp segment remembering and SACK.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(raw_mode==mode_icmp)
|
||||
|
14
network.h
14
network.h
@@ -5,12 +5,13 @@
|
||||
* Author: wangyu
|
||||
*/
|
||||
|
||||
#ifndef NETWORK_H_
|
||||
#define NETWORK_H_
|
||||
#ifndef UDP2RAW_NETWORK_H_
|
||||
#define UDP2RAW_NETWORK_H_
|
||||
|
||||
extern int raw_recv_fd;
|
||||
extern int raw_send_fd;
|
||||
extern int seq_mode;
|
||||
extern int max_seq_mode;
|
||||
extern int filter_port;
|
||||
extern u32_t bind_address_uint32;
|
||||
extern int disable_bpf_filter;
|
||||
@@ -54,6 +55,7 @@ struct packet_info_t //todo change this to union
|
||||
|
||||
u32_t seq,ack_seq;
|
||||
|
||||
u32_t ack_seq_counter;
|
||||
|
||||
u32_t ts,ts_ack;
|
||||
|
||||
@@ -64,6 +66,8 @@ struct packet_info_t //todo change this to union
|
||||
|
||||
sockaddr_ll addr_ll;
|
||||
|
||||
i32_t data_len;
|
||||
|
||||
packet_info_t();
|
||||
};
|
||||
|
||||
@@ -72,10 +76,10 @@ struct raw_info_t
|
||||
packet_info_t send_info;
|
||||
packet_info_t recv_info;
|
||||
|
||||
int last_send_len;
|
||||
int last_recv_len;
|
||||
//int last_send_len;
|
||||
//int last_recv_len;
|
||||
|
||||
u32_t reserved_seq;
|
||||
u32_t reserved_send_seq;
|
||||
//uint32_t first_seq,first_ack_seq;
|
||||
|
||||
};//g_raw_info;
|
||||
|
Reference in New Issue
Block a user