forked from fw876/helloworld
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path103-Add-TPROXY-support-for-TCP-ssr-redir.patch
154 lines (146 loc) · 4.84 KB
/
103-Add-TPROXY-support-for-TCP-ssr-redir.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
--- a/completions/bash/ss-redir
+++ b/completions/bash/ss-redir
@@ -2,7 +2,7 @@ _ss_redir()
{
local cur prev opts ciphers
ciphers='rc4-md5 table rc4 aes-128-cfb aes-192-cfb aes-256-cfb aes-128-ctr aes-192-ctr aes-256-ctr bf-cfb camellia-128-cfb camellia-192-cfb camellia-256-cfb cast5-cfb des-cfb idea-cfb rc2-cfb seed-cfb salsa20 chacha20 and chacha20-ietf'
- opts='-s -b -p -k -f -t -m -c -a -n -u -U -v -h -A --mtu --help --mptcp -l'
+ opts='-s -b -p -k -f -t -m -c -a -n -u -U -T -v -h -A --mtu --help --mptcp -l'
cur=${COMP_WORDS[COMP_CWORD]}
prev="${COMP_WORDS[COMP_CWORD-1]}"
case "$prev" in
--- a/src/jconf.c
+++ b/src/jconf.c
@@ -338,7 +338,11 @@ read_jconf(const char *file)
check_json_value_type(value, json_boolean,
"invalid config file: option 'ipv6_first' must be a boolean");
conf.ipv6_first = value->u.boolean;
- }
+ } else if (strcmp(name, "tcp_tproxy") == 0) {
+ check_json_value_type(value, json_boolean,
+ "invalid config file: option 'tcp_tproxy' must be a boolean");
+ conf.tcp_tproxy = value->u.boolean;
+ }
}
}
} else {
--- a/src/jconf.h
+++ b/src/jconf.h
@@ -105,6 +105,7 @@ typedef struct {
int mtu;
int mptcp;
int ipv6_first;
+ int tcp_tproxy;
} jconf_t;
jconf_t *read_jconf(const char *file);
--- a/src/redir.c
+++ b/src/redir.c
@@ -71,6 +71,14 @@
#define IP6T_SO_ORIGINAL_DST 80
#endif
+#ifndef IP_TRANSPARENT
+#define IP_TRANSPARENT 19
+#endif
+
+#ifndef IPV6_TRANSPARENT
+#define IPV6_TRANSPARENT 75
+#endif
+
#include "includeobfs.h" // I don't want to modify makefile
#include "jconf.h"
@@ -101,18 +109,28 @@ static struct cork_dllist inactive_profi
static listen_ctx_t *current_profile;
static struct cork_dllist all_connections;
+static int tcp_tproxy = 0; /* use tproxy instead of redirect (for tcp) */
+
int
getdestaddr(int fd, struct sockaddr_storage *destaddr)
{
socklen_t socklen = sizeof(*destaddr);
int error = 0;
- error = getsockopt(fd, SOL_IPV6, IP6T_SO_ORIGINAL_DST, destaddr, &socklen);
- if (error) { // Didn't find a proper way to detect IP version.
- error = getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, destaddr, &socklen);
- if (error) {
- return -1;
- }
+ if (tcp_tproxy) {
+ error = getsockname(fd, (void *)destaddr, &socklen);
+ } else {
+ error = getsockopt(fd, SOL_IPV6, IP6T_SO_ORIGINAL_DST, destaddr, &socklen);
+ if (error) { // Didn't find a proper way to detect IP version.
+ error = getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, destaddr, &socklen);
+ if (error) {
+ return -1;
+ }
+ }
+ }
+
+ if (error) {
+ return -1;
}
return 0;
}
@@ -164,6 +182,23 @@ create_and_bind(const char *addr, const
if (err == 0) {
LOGI("tcp port reuse enabled");
}
+
+ if (tcp_tproxy) {
+ int level = 0, optname = 0;
+ if (rp->ai_family == AF_INET) {
+ level = IPPROTO_IP;
+ optname = IP_TRANSPARENT;
+ } else {
+ level = IPPROTO_IPV6;
+ optname = IPV6_TRANSPARENT;
+ }
+
+ if (setsockopt(listen_sock, level, optname, &opt, sizeof(opt)) != 0) {
+ ERROR("setsockopt IP_TRANSPARENT");
+ exit(EXIT_FAILURE);
+ }
+ LOGI("tcp tproxy mode enabled");
+ }
s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen);
if (s == 0) {
@@ -1094,7 +1129,7 @@ main(int argc, char **argv)
USE_TTY();
- while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:c:b:a:n:huUvA6"
+ while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:c:b:a:n:huUTvA6"
"O:o:G:g:",
long_options, &option_index)) != -1) {
switch (c) {
@@ -1169,6 +1204,9 @@ main(int argc, char **argv)
case 'U':
mode = UDP_ONLY;
break;
+ case 'T':
+ tcp_tproxy = 1;
+ break;
case 'v':
verbose = 1;
break;
@@ -1255,6 +1293,9 @@ main(int argc, char **argv)
if (mode == TCP_ONLY) {
mode = conf->mode;
}
+ if (tcp_tproxy == 0) {
+ tcp_tproxy = conf->tcp_tproxy;
+ }
if (mtu == 0) {
mtu = conf->mtu;
}
--- a/src/utils.c
+++ b/src/utils.c
@@ -342,6 +342,10 @@ usage()
#endif
printf(
" [-U] Enable UDP relay and disable TCP relay.\n");
+#ifdef MODULE_REDIR
+ printf(
+ " [-T] Use tproxy instead of redirect (for tcp).\n");
+#endif
#ifdef MODULE_REMOTE
printf(
" [-6] Resovle hostname to IPv6 address first.\n");