mirror of
https://github.com/wangyu-/udp2raw.git
synced 2025-09-17 04:34:27 +08:00
Compare commits
9 Commits
revert-455
...
0c33896a46
Author | SHA1 | Date | |
---|---|---|---|
|
0c33896a46 | ||
|
4e6e1e6a97 | ||
|
e42f0e5732 | ||
|
f49e6adedf | ||
|
d1a9bcc4fb | ||
|
bc8bd8c2f8 | ||
|
ca16c3a5e6 | ||
|
7abe19c7d9 | ||
|
ec416515f3 |
13
Dockerfile
13
Dockerfile
@@ -1,13 +0,0 @@
|
||||
FROM alpine:3.6 as builder
|
||||
|
||||
WORKDIR /
|
||||
|
||||
RUN apk add --no-cache git build-base linux-headers && \
|
||||
git clone https://github.com/wangyu-/udp2raw-tunnel.git && \
|
||||
cd udp2raw-tunnel && \
|
||||
make dynamic
|
||||
|
||||
FROM alpine:3.6
|
||||
RUN apk add --no-cache libstdc++ iptables
|
||||
COPY --from=builder /udp2raw-tunnel/udp2raw_dynamic /bin/
|
||||
ENTRYPOINT [ "/bin/udp2raw_dynamic" ]
|
@@ -81,7 +81,7 @@ Assume your UDP is blocked or being QOS-ed or just poorly supported. Assume your
|
||||
Now,an encrypted raw tunnel has been established between client and server through TCP port 4096. Connecting to UDP port 3333 at the client side is equivalent to connecting to port 7777 at the server side. No UDP traffic will be exposed.
|
||||
|
||||
### Note
|
||||
To run on Android, check [Android_Guide](/doc/android_guide.md)
|
||||
To run on Android, check [Android_Guide](https://github.com/wangyu-/udp2raw/wiki/Android-Guide)
|
||||
|
||||
`-a` option automatically adds an iptables rule (or a few iptables rules) for you, udp2raw relies on this iptables rule to work stably. Be aware you dont forget `-a` (its a common mistake). If you dont want udp2raw to add iptables rule automatically, you can add it manually(take a look at `-g` option) and omit `-a`.
|
||||
|
||||
|
2
common.h
2
common.h
@@ -163,6 +163,8 @@ extern int force_socket_buf;
|
||||
|
||||
extern int g_fix_gro;
|
||||
|
||||
extern int g_tcp_spa;
|
||||
|
||||
/*
|
||||
struct ip_port_t
|
||||
{
|
||||
|
1
git_version.h
Normal file
1
git_version.h
Normal file
@@ -0,0 +1 @@
|
||||
const char *gitversion = "e42f0e573221c5e0146c02fd5d71f32aa93c7221";
|
2
makefile
2
makefile
@@ -103,7 +103,7 @@ linux:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${PCAP} ${FLAGS} -lrt -ggdb -static -O2 ${MP}
|
||||
|
||||
freebsd:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${PCAP} ${FLAGS} -lrt -ggdb -static -O2 ${MP}
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${PCAP} ${FLAGS} -lrt -ggdb -static -libverbs -O2 ${MP}
|
||||
|
||||
mac:git_version
|
||||
${cc_local} -o ${NAME}_$@ -I. ${SOURCES} ${PCAP} ${FLAGS} -ggdb -O2 ${MP}
|
||||
|
8
misc.cpp
8
misc.cpp
@@ -148,7 +148,9 @@ void print_help() {
|
||||
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(" 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("client options:\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},
|
||||
#endif
|
||||
{"fix-gro", no_argument, 0, 1},
|
||||
{"tcp-spa", no_argument, 0, 1},
|
||||
{NULL, 0, 0, 0}};
|
||||
|
||||
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) {
|
||||
mylog(log_info, "--fix-gro enabled\n");
|
||||
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 {
|
||||
mylog(log_warn, "ignored unknown long option ,option_index:%d code:<%x>\n", option_index, optopt);
|
||||
}
|
||||
|
77
network.cpp
77
network.cpp
@@ -259,6 +259,40 @@ tcpdump -i eth1 ip and icmp -dd
|
||||
*/
|
||||
#endif
|
||||
|
||||
//tcp option for SPA
|
||||
int g_tcp_spa = 0;
|
||||
typedef struct tcpopt_data {
|
||||
__u8 opcode;
|
||||
__u8 opsize;
|
||||
__u16 reserve;
|
||||
__u32 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() {
|
||||
src_port = 0;
|
||||
dst_port = 0;
|
||||
@@ -702,7 +736,7 @@ void init_filter(int port) {
|
||||
}
|
||||
}
|
||||
|
||||
int dummy;
|
||||
int dummy=0;
|
||||
|
||||
int ret = setsockopt(raw_recv_fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy)); // in case i forgot to remove
|
||||
if (ret != 0) {
|
||||
@@ -841,7 +875,7 @@ void init_filter(int port) {
|
||||
void remove_filter() {
|
||||
filter_port = 0;
|
||||
#ifdef UDP2RAW_LINUX
|
||||
int dummy;
|
||||
int dummy=0;
|
||||
int ret = setsockopt(raw_recv_fd, SOL_SOCKET, SO_DETACH_FILTER, &dummy, sizeof(dummy));
|
||||
if (ret != 0) {
|
||||
mylog(log_debug, "error remove fiter\n");
|
||||
@@ -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++] = 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 {
|
||||
tcph->doff = 8;
|
||||
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.ts = 0;
|
||||
|
||||
bool no_found_spa_opt = true;
|
||||
|
||||
char *ptr = option_begin;
|
||||
// char *option_end=tcp_begin+tcp_hdr_len;
|
||||
while (ptr < option_end) {
|
||||
@@ -2143,6 +2189,22 @@ 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
|
||||
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 -1;
|
||||
}
|
||||
tcpopt_data_t *opt = (tcpopt_data_t*)ptr;
|
||||
uint32_t csum = checksum(htonl(recv_info.ts), key_string);
|
||||
if(opt->csum == htonl(csum)){
|
||||
//mylog(log_info, "SPA csum match succeed\n");
|
||||
no_found_spa_opt = false;
|
||||
} else {
|
||||
mylog(log_info, "SPA csum match failed\n");
|
||||
return -2;
|
||||
}
|
||||
ptr += sizeof(tcpopt_data_t);
|
||||
} else {
|
||||
if (ptr + 1 >= option_end) {
|
||||
mylog(log_trace, "invaild option ptr+1==option_end\n");
|
||||
@@ -2160,7 +2222,10 @@ int parse_tcp_option(char *option_begin, char *option_end, packet_info_t &recv_i
|
||||
// printf("!");
|
||||
}
|
||||
// printf("\n");
|
||||
|
||||
if(recv_info.syn == 1 && recv_info.ack == 0 && g_tcp_spa && no_found_spa_opt) {
|
||||
mylog(log_info, "No found spa opt, pkt drop\n");
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
*/
|
||||
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.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);
|
||||
|
||||
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_ack_seq=recv_info.ack_seq;
|
||||
u32_t last_ack_seq = recv_info.ack_seq;
|
||||
|
@@ -226,12 +226,12 @@ struct packet_info_t // todo change this to union
|
||||
|
||||
bool has_ts;
|
||||
|
||||
i32_t data_len;
|
||||
|
||||
#ifdef UDP2RAW_LINUX
|
||||
sockaddr_ll addr_ll;
|
||||
#endif
|
||||
|
||||
i32_t data_len;
|
||||
|
||||
packet_info_t();
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user