103-Add-TPROXY-support-for-TCP-ssr-redir.patch 4.8 KB

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