mirror of
https://github.com/wangyu-/udp2raw.git
synced 2025-10-16 02:45:34 +08:00
Compare commits
4 Commits
unified
...
fa995e9f09
Author | SHA1 | Date | |
---|---|---|---|
|
fa995e9f09 | ||
|
b6c6813d41 | ||
|
9045264d37 | ||
|
4e6e1e6a97 |
16
README.md
16
README.md
@@ -90,7 +90,7 @@ To run on Android, check [Android_Guide](https://github.com/wangyu-/udp2raw/wiki
|
|||||||
### Usage
|
### Usage
|
||||||
```
|
```
|
||||||
udp2raw-tunnel
|
udp2raw-tunnel
|
||||||
git version:4623f878e0 build date:Nov 3 2024 23:15:46
|
git version:6e1df4b39f build date:Oct 24 2017 09:21:15
|
||||||
repository: https://github.com/wangyu-/udp2raw-tunnel
|
repository: https://github.com/wangyu-/udp2raw-tunnel
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
@@ -98,16 +98,14 @@ usage:
|
|||||||
run as server : ./this_program -s -l server_listen_ip:server_port -r remote_address:remote_port [options]
|
run as server : ./this_program -s -l server_listen_ip:server_port -r remote_address:remote_port [options]
|
||||||
|
|
||||||
common options,these options must be same on both side:
|
common options,these options must be same on both side:
|
||||||
--raw-mode <string> available values:faketcp(default),udp,icmp and easy-faketcp
|
--raw-mode <string> avaliable values:faketcp(default),udp,icmp
|
||||||
-k,--key <string> password to gen symetric key,default:"secret key"
|
-k,--key <string> password to gen symetric key,default:"secret key"
|
||||||
--cipher-mode <string> available values:aes128cfb,aes128cbc(default),xor,none
|
--cipher-mode <string> avaliable values:aes128cbc(default),xor,none
|
||||||
--auth-mode <string> available values:hmac_sha1,md5(default),crc32,simple,none
|
--auth-mode <string> avaliable values:hmac_sha1,md5(default),crc32,simple,none
|
||||||
-a,--auto-rule auto add (and delete) iptables rule
|
-a,--auto-rule auto add (and delete) iptables rule
|
||||||
-g,--gen-rule generate iptables rule then exit,so that you can copy and
|
-g,--gen-rule generate iptables rule then exit,so that you can copy and
|
||||||
add it manually.overrides -a
|
add it manually.overrides -a
|
||||||
--disable-anti-replay disable anti-replay,not suggested
|
--disable-anti-replay disable anti-replay,not suggested
|
||||||
--fix-gro try to fix huge packet caused by GRO. this option is at an early stage.
|
|
||||||
make sure client and server are at same version.
|
|
||||||
client options:
|
client options:
|
||||||
--source-ip <ip> force source-ip for raw socket
|
--source-ip <ip> force source-ip for raw socket
|
||||||
--source-port <port> force source-port for raw socket,tcp/udp only
|
--source-port <port> force source-port for raw socket,tcp/udp only
|
||||||
@@ -123,7 +121,6 @@ other options:
|
|||||||
--disable-color disable log color
|
--disable-color disable log color
|
||||||
--disable-bpf disable the kernel space filter,most time its not necessary
|
--disable-bpf disable the kernel space filter,most time its not necessary
|
||||||
unless you suspect there is a bug
|
unless you suspect there is a bug
|
||||||
--dev <string> bind raw socket to a device, not necessary but improves performance
|
|
||||||
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
|
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
|
||||||
--force-sock-buf bypass system limitation while setting sock-buf
|
--force-sock-buf bypass system limitation while setting sock-buf
|
||||||
--seq-mode <number> seq increase mode for faketcp:
|
--seq-mode <number> seq increase mode for faketcp:
|
||||||
@@ -136,14 +133,11 @@ other options:
|
|||||||
--lower-level <string> send packets at OSI level 2, format:'if_name#dest_mac_adress'
|
--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
|
ie:'eth0#00:23:45:67:89:b9'.or try '--lower-level auto' to obtain
|
||||||
the parameter automatically,specify it manually if 'auto' failed
|
the parameter automatically,specify it manually if 'auto' failed
|
||||||
--wait-lock wait for xtables lock while invoking iptables, need iptables v1.4.20+
|
|
||||||
--gen-add generate iptables rule and add it permanently,then exit.overrides -g
|
--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
|
--keep-rule monitor iptables and auto re-add if necessary.implys -a
|
||||||
--hb-len <number> length of heart-beat packet, >=0 and <=1500
|
|
||||||
--mtu-warn <number> mtu warning threshold, unit:byte, default:1375
|
|
||||||
--clear clear any iptables rules added by this program.overrides everything
|
--clear clear any iptables rules added by this program.overrides everything
|
||||||
--retry-on-error retry on error, allow to start udp2raw before network is initialized
|
|
||||||
-h,--help print this help message
|
-h,--help print this help message
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Iptables rules,`-a` and `-g`
|
### Iptables rules,`-a` and `-g`
|
||||||
|
2
common.h
2
common.h
@@ -163,6 +163,8 @@ extern int force_socket_buf;
|
|||||||
|
|
||||||
extern int g_fix_gro;
|
extern int g_fix_gro;
|
||||||
|
|
||||||
|
extern int g_tcp_spa;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct ip_port_t
|
struct ip_port_t
|
||||||
{
|
{
|
||||||
|
@@ -435,7 +435,7 @@ int send_safer(conn_info_t &conn_info, char type, const char *data, int len) //
|
|||||||
if (cipher_mode == cipher_xor) {
|
if (cipher_mode == cipher_xor) {
|
||||||
send_data_buf2[0] ^= gro_xor[0];
|
send_data_buf2[0] ^= gro_xor[0];
|
||||||
send_data_buf2[1] ^= gro_xor[1];
|
send_data_buf2[1] ^= gro_xor[1];
|
||||||
} else if (cipher_mode == cipher_aes128cbc || cipher_mode == cipher_aes128cfb) {
|
} else if (cipher_mode == cipher_aes128cbc || cipher_mode == cipher_aes128cbc) {
|
||||||
aes_ecb_encrypt1(send_data_buf2);
|
aes_ecb_encrypt1(send_data_buf2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -586,7 +586,7 @@ int recv_safer_multi(conn_info_t &conn_info, vector<char> &type_arr, vector<stri
|
|||||||
if (cipher_mode == cipher_xor) {
|
if (cipher_mode == cipher_xor) {
|
||||||
recv_data[0] ^= gro_xor[0];
|
recv_data[0] ^= gro_xor[0];
|
||||||
recv_data[1] ^= gro_xor[1];
|
recv_data[1] ^= gro_xor[1];
|
||||||
} else if (cipher_mode == cipher_aes128cbc || cipher_mode == cipher_aes128cfb) {
|
} else if (cipher_mode == cipher_aes128cbc || cipher_mode == cipher_aes128cbc) {
|
||||||
aes_ecb_decrypt1(recv_data);
|
aes_ecb_decrypt1(recv_data);
|
||||||
}
|
}
|
||||||
single_len = read_u16(recv_data);
|
single_len = read_u16(recv_data);
|
||||||
|
@@ -103,7 +103,7 @@ https://github.com/wangyu-/udp2raw-tunnel/releases
|
|||||||
### 命令选项
|
### 命令选项
|
||||||
```
|
```
|
||||||
udp2raw-tunnel
|
udp2raw-tunnel
|
||||||
git version:4623f878e0 build date:Nov 3 2024 23:15:46
|
git version:6e1df4b39f build date:Oct 24 2017 09:21:15
|
||||||
repository: https://github.com/wangyu-/udp2raw-tunnel
|
repository: https://github.com/wangyu-/udp2raw-tunnel
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
@@ -111,16 +111,14 @@ usage:
|
|||||||
run as server : ./this_program -s -l server_listen_ip:server_port -r remote_address:remote_port [options]
|
run as server : ./this_program -s -l server_listen_ip:server_port -r remote_address:remote_port [options]
|
||||||
|
|
||||||
common options,these options must be same on both side:
|
common options,these options must be same on both side:
|
||||||
--raw-mode <string> available values:faketcp(default),udp,icmp and easy-faketcp
|
--raw-mode <string> available values:faketcp(default),udp,icmp
|
||||||
-k,--key <string> password to gen symetric key,default:"secret key"
|
-k,--key <string> password to gen symetric key,default:"secret key"
|
||||||
--cipher-mode <string> available values:aes128cfb,aes128cbc(default),xor,none
|
--cipher-mode <string> available values:aes128cbc(default),xor,none
|
||||||
--auth-mode <string> available values:hmac_sha1,md5(default),crc32,simple,none
|
--auth-mode <string> available values:hmac_sha1,md5(default),crc32,simple,none
|
||||||
-a,--auto-rule auto add (and delete) iptables rule
|
-a,--auto-rule auto add (and delete) iptables rule
|
||||||
-g,--gen-rule generate iptables rule then exit,so that you can copy and
|
-g,--gen-rule generate iptables rule then exit,so that you can copy and
|
||||||
add it manually.overrides -a
|
add it manually.overrides -a
|
||||||
--disable-anti-replay disable anti-replay,not suggested
|
--disable-anti-replay disable anti-replay,not suggested
|
||||||
--fix-gro try to fix huge packet caused by GRO. this option is at an early stage.
|
|
||||||
make sure client and server are at same version.
|
|
||||||
client options:
|
client options:
|
||||||
--source-ip <ip> force source-ip for raw socket
|
--source-ip <ip> force source-ip for raw socket
|
||||||
--source-port <port> force source-port for raw socket,tcp/udp only
|
--source-port <port> force source-port for raw socket,tcp/udp only
|
||||||
@@ -136,7 +134,6 @@ other options:
|
|||||||
--disable-color disable log color
|
--disable-color disable log color
|
||||||
--disable-bpf disable the kernel space filter,most time its not necessary
|
--disable-bpf disable the kernel space filter,most time its not necessary
|
||||||
unless you suspect there is a bug
|
unless you suspect there is a bug
|
||||||
--dev <string> bind raw socket to a device, not necessary but improves performance
|
|
||||||
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
|
--sock-buf <number> buf size for socket,>=10 and <=10240,unit:kbyte,default:1024
|
||||||
--force-sock-buf bypass system limitation while setting sock-buf
|
--force-sock-buf bypass system limitation while setting sock-buf
|
||||||
--seq-mode <number> seq increase mode for faketcp:
|
--seq-mode <number> seq increase mode for faketcp:
|
||||||
@@ -149,14 +146,11 @@ other options:
|
|||||||
--lower-level <string> send packets at OSI level 2, format:'if_name#dest_mac_adress'
|
--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
|
ie:'eth0#00:23:45:67:89:b9'.or try '--lower-level auto' to obtain
|
||||||
the parameter automatically,specify it manually if 'auto' failed
|
the parameter automatically,specify it manually if 'auto' failed
|
||||||
--wait-lock wait for xtables lock while invoking iptables, need iptables v1.4.20+
|
|
||||||
--gen-add generate iptables rule and add it permanently,then exit.overrides -g
|
--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
|
--keep-rule monitor iptables and auto re-add if necessary.implys -a
|
||||||
--hb-len <number> length of heart-beat packet, >=0 and <=1500
|
|
||||||
--mtu-warn <number> mtu warning threshold, unit:byte, default:1375
|
|
||||||
--clear clear any iptables rules added by this program.overrides everything
|
--clear clear any iptables rules added by this program.overrides everything
|
||||||
--retry-on-error retry on error, allow to start udp2raw before network is initialized
|
|
||||||
-h,--help print this help message
|
-h,--help print this help message
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### iptables 规则,`-a`和`-g`
|
### iptables 规则,`-a`和`-g`
|
||||||
@@ -275,4 +269,3 @@ raw_mode: faketcp cipher_mode: aes128cbc auth_mode: md5
|
|||||||
|
|
||||||
https://github.com/wangyu-/udp2raw-tunnel/wiki
|
https://github.com/wangyu-/udp2raw-tunnel/wiki
|
||||||
|
|
||||||
|
|
||||||
|
1
git_version.h
Normal file
1
git_version.h
Normal file
@@ -0,0 +1 @@
|
|||||||
|
const char *gitversion = "e42f0e573221c5e0146c02fd5d71f32aa93c7221";
|
8
misc.cpp
8
misc.cpp
@@ -148,7 +148,9 @@ void print_help() {
|
|||||||
printf(" --disable-anti-replay disable anti-replay,not suggested\n");
|
printf(" --disable-anti-replay disable anti-replay,not suggested\n");
|
||||||
printf(" --fix-gro try to fix huge packet caused by GRO. this option is at an early stage.\n");
|
printf(" --fix-gro try to fix huge packet caused by GRO. this option is at an early stage.\n");
|
||||||
printf(" make sure client and server are at same version.\n");
|
printf(" make sure client and server are at same version.\n");
|
||||||
|
printf(" --tcp-spa TCP SPA mode to avoid port scanning.\n");
|
||||||
|
printf(" when enable on server mode, will check SYN's option.\n");
|
||||||
|
|
||||||
// printf("\n");
|
// printf("\n");
|
||||||
printf("client options:\n");
|
printf("client options:\n");
|
||||||
printf(" --source-ip <ip> force source-ip for raw socket\n");
|
printf(" --source-ip <ip> force source-ip for raw socket\n");
|
||||||
@@ -296,6 +298,7 @@ void process_arg(int argc, char *argv[]) // process all options
|
|||||||
{"no-pcap-mutex", no_argument, 0, 1},
|
{"no-pcap-mutex", no_argument, 0, 1},
|
||||||
#endif
|
#endif
|
||||||
{"fix-gro", no_argument, 0, 1},
|
{"fix-gro", no_argument, 0, 1},
|
||||||
|
{"tcp-spa", no_argument, 0, 1},
|
||||||
{NULL, 0, 0, 0}};
|
{NULL, 0, 0, 0}};
|
||||||
|
|
||||||
process_log_level(argc, argv);
|
process_log_level(argc, argv);
|
||||||
@@ -677,6 +680,9 @@ void process_arg(int argc, char *argv[]) // process all options
|
|||||||
} else if (strcmp(long_options[option_index].name, "fix-gro") == 0) {
|
} else if (strcmp(long_options[option_index].name, "fix-gro") == 0) {
|
||||||
mylog(log_info, "--fix-gro enabled\n");
|
mylog(log_info, "--fix-gro enabled\n");
|
||||||
g_fix_gro = 1;
|
g_fix_gro = 1;
|
||||||
|
} else if (strcmp(long_options[option_index].name, "tcp-spa") == 0) {
|
||||||
|
mylog(log_info, "--tcp-spa enabled\n");
|
||||||
|
g_tcp_spa = 1;
|
||||||
} else {
|
} else {
|
||||||
mylog(log_warn, "ignored unknown long option ,option_index:%d code:<%x>\n", option_index, optopt);
|
mylog(log_warn, "ignored unknown long option ,option_index:%d code:<%x>\n", option_index, optopt);
|
||||||
}
|
}
|
||||||
|
71
network.cpp
71
network.cpp
@@ -259,6 +259,40 @@ tcpdump -i eth1 ip and icmp -dd
|
|||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//tcp option for SPA
|
||||||
|
int g_tcp_spa = 0;
|
||||||
|
typedef struct tcpopt_data {
|
||||||
|
uint8_t opcode;
|
||||||
|
uint8_t opsize;
|
||||||
|
uint16_t reserve;
|
||||||
|
uint32_t csum;
|
||||||
|
}tcpopt_data_t;
|
||||||
|
|
||||||
|
#define TCPOPT_SPA 233
|
||||||
|
|
||||||
|
#define HASH_PRIME 16777619
|
||||||
|
#define HASH_OFFSET 2166136261U
|
||||||
|
|
||||||
|
//FNV-1a from GPT
|
||||||
|
uint32_t checksum(uint32_t timestamp, const char* key) {
|
||||||
|
uint32_t hash = HASH_OFFSET;
|
||||||
|
const char* ptr = key;
|
||||||
|
size_t key_len = strlen(key);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < key_len; i++) {
|
||||||
|
hash ^= (uint32_t)ptr[i];
|
||||||
|
hash *= HASH_PRIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < sizeof(uint32_t); i++) {
|
||||||
|
hash ^= (uint32_t)(timestamp & 0xFF);
|
||||||
|
hash *= HASH_PRIME;
|
||||||
|
timestamp >>= 8;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
//--------------
|
||||||
|
|
||||||
packet_info_t::packet_info_t() {
|
packet_info_t::packet_info_t() {
|
||||||
src_port = 0;
|
src_port = 0;
|
||||||
dst_port = 0;
|
dst_port = 0;
|
||||||
@@ -1679,6 +1713,16 @@ int send_raw_tcp(raw_info_t &raw_info, const char *payload, int payloadlen) { /
|
|||||||
send_raw_tcp_buf[i++] = 0x03;
|
send_raw_tcp_buf[i++] = 0x03;
|
||||||
send_raw_tcp_buf[i++] = 0x03;
|
send_raw_tcp_buf[i++] = 0x03;
|
||||||
send_raw_tcp_buf[i++] = wscale;
|
send_raw_tcp_buf[i++] = wscale;
|
||||||
|
|
||||||
|
if(g_tcp_spa && tcph->ack == 0) {
|
||||||
|
tcph->doff = 12;
|
||||||
|
tcpopt_data_t opt = {TCPOPT_SPA, sizeof(tcpopt_data_t), 0, 0};
|
||||||
|
uint32_t csum = checksum(ts, key_string);
|
||||||
|
opt.csum = htonl(csum);
|
||||||
|
memcpy(&send_raw_tcp_buf[i], &opt, opt.opsize);
|
||||||
|
i += opt.opsize;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
tcph->doff = 8;
|
tcph->doff = 8;
|
||||||
int i = sizeof(my_tcphdr);
|
int i = sizeof(my_tcphdr);
|
||||||
@@ -2113,6 +2157,8 @@ int parse_tcp_option(char *option_begin, char *option_end, packet_info_t &recv_i
|
|||||||
recv_info.has_ts = 0;
|
recv_info.has_ts = 0;
|
||||||
recv_info.ts = 0;
|
recv_info.ts = 0;
|
||||||
|
|
||||||
|
tcpopt_data_t *opt = NULL;
|
||||||
|
|
||||||
char *ptr = option_begin;
|
char *ptr = option_begin;
|
||||||
// char *option_end=tcp_begin+tcp_hdr_len;
|
// char *option_end=tcp_begin+tcp_hdr_len;
|
||||||
while (ptr < option_end) {
|
while (ptr < option_end) {
|
||||||
@@ -2143,6 +2189,14 @@ int parse_tcp_option(char *option_begin, char *option_end, packet_info_t &recv_i
|
|||||||
|
|
||||||
// return 0;//we currently only parse ts, so just return after its found
|
// return 0;//we currently only parse ts, so just return after its found
|
||||||
ptr += 10;
|
ptr += 10;
|
||||||
|
} else if (recv_info.syn == 1 && recv_info.ack == 0
|
||||||
|
&& g_tcp_spa && (unsigned char)*ptr == TCPOPT_SPA) {
|
||||||
|
if (ptr + sizeof(tcpopt_data_t) > option_end) {
|
||||||
|
mylog(log_trace, "ptr+8>option_end for TCPOPT_SPA\n");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
opt = (tcpopt_data_t*)ptr;
|
||||||
|
ptr += sizeof(tcpopt_data_t);
|
||||||
} else {
|
} else {
|
||||||
if (ptr + 1 >= option_end) {
|
if (ptr + 1 >= option_end) {
|
||||||
mylog(log_trace, "invaild option ptr+1==option_end\n");
|
mylog(log_trace, "invaild option ptr+1==option_end\n");
|
||||||
@@ -2160,7 +2214,18 @@ int parse_tcp_option(char *option_begin, char *option_end, packet_info_t &recv_i
|
|||||||
// printf("!");
|
// printf("!");
|
||||||
}
|
}
|
||||||
// printf("\n");
|
// printf("\n");
|
||||||
|
if(recv_info.syn == 1 && recv_info.ack == 0 && g_tcp_spa) {
|
||||||
|
if(opt == NULL) {
|
||||||
|
mylog(log_trace, "No found spa opt, pkt drop\n");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t csum = checksum(htonl(recv_info.ts), key_string);
|
||||||
|
if(opt->csum != htonl(csum)){
|
||||||
|
mylog(log_trace, "SPA csum match failed\n");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int recv_raw_tcp(raw_info_t &raw_info, char *&payload, int &payloadlen) {
|
int recv_raw_tcp(raw_info_t &raw_info, char *&payload, int &payloadlen) {
|
||||||
@@ -2294,7 +2359,8 @@ int recv_raw_tcp(raw_info_t &raw_info, char *&payload, int &payloadlen) {
|
|||||||
}
|
}
|
||||||
printf("<%d %d>\n",recv_info.ts,recv_info.ts_ack);
|
printf("<%d %d>\n",recv_info.ts,recv_info.ts_ack);
|
||||||
*/
|
*/
|
||||||
parse_tcp_option(tcp_option, option_end, recv_info);
|
|
||||||
|
//parse_tcp_option(tcp_option, option_end, recv_info);
|
||||||
|
|
||||||
recv_info.ack = tcph->ack;
|
recv_info.ack = tcph->ack;
|
||||||
recv_info.syn = tcph->syn;
|
recv_info.syn = tcph->syn;
|
||||||
@@ -2304,6 +2370,9 @@ int recv_raw_tcp(raw_info_t &raw_info, char *&payload, int &payloadlen) {
|
|||||||
|
|
||||||
recv_info.seq = ntohl(tcph->seq);
|
recv_info.seq = ntohl(tcph->seq);
|
||||||
|
|
||||||
|
if(-2 == parse_tcp_option(tcp_option, option_end, recv_info))
|
||||||
|
return -1;
|
||||||
|
|
||||||
// recv_info.last_last_ack_seq=recv_info.last_ack_seq;
|
// recv_info.last_last_ack_seq=recv_info.last_ack_seq;
|
||||||
// recv_info.last_ack_seq=recv_info.ack_seq;
|
// recv_info.last_ack_seq=recv_info.ack_seq;
|
||||||
u32_t last_ack_seq = recv_info.ack_seq;
|
u32_t last_ack_seq = recv_info.ack_seq;
|
||||||
|
Reference in New Issue
Block a user