🌴 Sync 2026-03-05 23:51:42

This commit is contained in:
github-actions[bot] committed 2026-03-05 23:51:42 +08:00
1 parent 97c049ed0a
commit 0acff03804
14253 files changed
+3893239

No files matched your search

@@ -0,0 +1,397 @@
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@ build/
.deps/
/Makefile
src/Makefile
+server/Makefile
libev/Makefile
libudns/Makefile
libcork/Makefile
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
if USE_SYSTEM_SHARED_LIB
-SUBDIRS = libcork libipset src
+SUBDIRS = libcork libipset src server
else
-SUBDIRS = libsodium libcork libipset libudns libev src
+SUBDIRS = libsodium libcork libipset libudns libev src server
endif
if ENABLE_DOCUMENTATION
--- a/Makefile.in
+++ b/Makefile.in
@@ -195,7 +195,7 @@ am__define_uniq_tagged_files = \
ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
-DIST_SUBDIRS = libsodium libcork libipset libudns libev src doc
+DIST_SUBDIRS = libsodium libcork libipset libudns libev src server doc
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(srcdir)/shadowsocks-libev.pc.in $(top_srcdir)/auto/ar-lib \
$(top_srcdir)/auto/compile $(top_srcdir)/auto/config.guess \
@@ -377,8 +377,9 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@USE_SYSTEM_SHARED_LIB_FALSE@SUBDIRS = libsodium libcork libipset \
-@USE_SYSTEM_SHARED_LIB_FALSE@ libudns libev src $(am__append_1)
-@USE_SYSTEM_SHARED_LIB_TRUE@SUBDIRS = libcork libipset src \
+@USE_SYSTEM_SHARED_LIB_FALSE@ libudns libev src server \
+@USE_SYSTEM_SHARED_LIB_FALSE@ $(am__append_1)
+@USE_SYSTEM_SHARED_LIB_TRUE@SUBDIRS = libcork libipset src server \
@USE_SYSTEM_SHARED_LIB_TRUE@ $(am__append_1)
ACLOCAL_AMFLAGS = -I m4
pkgconfiglibdir = $(libdir)/pkgconfig
--- a/configure
+++ b/configure
@@ -649,7 +649,6 @@ PTHREAD_CC
ax_pthread_config
INET_NTOP_LIB
MV
-RM
GZIP
XMLTO
ASCIIDOC
@@ -757,6 +756,7 @@ infodir
docdir
oldincludedir
includedir
+runstatedir
localstatedir
sharedstatedir
sysconfdir
@@ -857,6 +857,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1109,6 +1110,15 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1246,7 +1256,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
+ libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@@ -1399,6 +1409,7 @@ Fine tuning of the installation director
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -2472,8 +2483,8 @@ ac_configure="$SHELL $ac_aux_dir/configu
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -3783,7 +3794,7 @@ $as_echo "$ac_cv_safe_to_define___extens
-am__api_version='1.14'
+am__api_version='1.15'
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -3972,7 +3983,7 @@ else
$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
fi
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -4363,8 +4374,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}ma
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
mkdir_p='$(MKDIR_P)'
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AMTAR='$${TAR-tar}'
@@ -4549,6 +4560,7 @@ END
as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
fi
fi
+
if test -n "$ac_tool_prefix"; then
for ac_prog in ar lib "link -lib"
do
@@ -12494,47 +12506,6 @@ $as_echo "no" >&6; }
fi
- # Extract the first word of "rm", so it can be a program name with args.
-set dummy rm; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_RM+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- case $RM in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_RM="$RM" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_RM" && ac_cv_path_RM="rm"
- ;;
-esac
-fi
-RM=$ac_cv_path_RM
-if test -n "$RM"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RM" >&5
-$as_echo "$RM" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
# Extract the first word of "mv", so it can be a program name with args.
set dummy mv; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -16204,15 +16175,162 @@ $as_echo "#define HAVE_IPv6 1" >>confdef
if test -z "$USE_SYSTEM_SHARED_LIB_TRUE"; then :
- else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sodium_init in -lsodium" >&5
+$as_echo_n "checking for sodium_init in -lsodium... " >&6; }
+if ${ac_cv_lib_sodium_sodium_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsodium $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sodium_init ();
+int
+main ()
+{
+return sodium_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_sodium_sodium_init=yes
+else
+ ac_cv_lib_sodium_sodium_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sodium_sodium_init" >&5
+$as_echo "$ac_cv_lib_sodium_sodium_init" >&6; }
+if test "x$ac_cv_lib_sodium_sodium_init" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSODIUM 1
+_ACEOF
+
+ LIBS="-lsodium $LIBS"
+
+else
+
+ as_fn_error $? "Couldn't find libsodium. Try installing libsodium-dev[el]." "$LINENO" 5
+
+fi
+
+
+else
subdirs="$subdirs libsodium"
fi
-ac_config_files="$ac_config_files shadowsocks-libev.pc Makefile libcork/Makefile libipset/Makefile src/Makefile"
+ac_config_files="$ac_config_files shadowsocks-libev.pc Makefile libcork/Makefile libipset/Makefile src/Makefile server/Makefile"
if test -z "$USE_SYSTEM_SHARED_LIB_TRUE"; then :
- else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dns_dnlen in -ludns" >&5
+$as_echo_n "checking for dns_dnlen in -ludns... " >&6; }
+if ${ac_cv_lib_udns_dns_dnlen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ludns $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dns_dnlen ();
+int
+main ()
+{
+return dns_dnlen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_udns_dns_dnlen=yes
+else
+ ac_cv_lib_udns_dns_dnlen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_udns_dns_dnlen" >&5
+$as_echo "$ac_cv_lib_udns_dns_dnlen" >&6; }
+if test "x$ac_cv_lib_udns_dns_dnlen" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBUDNS 1
+_ACEOF
+
+ LIBS="-ludns $LIBS"
+
+else
+ as_fn_error $? "Couldn't find libudns. Try installing libudns-dev or udns-devel." "$LINENO" 5
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ev_loop_destroy in -lev" >&5
+$as_echo_n "checking for ev_loop_destroy in -lev... " >&6; }
+if ${ac_cv_lib_ev_ev_loop_destroy+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lev $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ev_loop_destroy ();
+int
+main ()
+{
+return ev_loop_destroy ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ev_ev_loop_destroy=yes
+else
+ ac_cv_lib_ev_ev_loop_destroy=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ev_ev_loop_destroy" >&5
+$as_echo "$ac_cv_lib_ev_ev_loop_destroy" >&6; }
+if test "x$ac_cv_lib_ev_ev_loop_destroy" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBEV 1
+_ACEOF
+
+ LIBS="-lev $LIBS"
+
+else
+ as_fn_error $? "Couldn't find libev. Try installing libev-dev[el]." "$LINENO" 5
+fi
+
+
+else
ac_config_files="$ac_config_files libudns/Makefile libev/Makefile"
fi
@@ -17258,6 +17376,7 @@ do
"libcork/Makefile") CONFIG_FILES="$CONFIG_FILES libcork/Makefile" ;;
"libipset/Makefile") CONFIG_FILES="$CONFIG_FILES libipset/Makefile" ;;
"src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+ "server/Makefile") CONFIG_FILES="$CONFIG_FILES server/Makefile" ;;
"libudns/Makefile") CONFIG_FILES="$CONFIG_FILES libudns/Makefile" ;;
"libev/Makefile") CONFIG_FILES="$CONFIG_FILES libev/Makefile" ;;
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
@@ -17958,8 +18077,8 @@ $as_echo X"$file" |
fi
cfgfile="${ofile}T"
- trap "$RM -f \"$cfgfile\"; exit 1" 1 2 15
- $RM -f "$cfgfile"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
--- a/configure.ac
+++ b/configure.ac
@@ -315,7 +315,8 @@ AC_CONFIG_FILES([ shadowsocks-libev.pc
Makefile
libcork/Makefile
libipset/Makefile
- src/Makefile])
+ src/Makefile
+ server/Makefile])
AM_COND_IF([USE_SYSTEM_SHARED_LIB],[
AC_CHECK_LIB([udns], [dns_dnlen], ,[AC_MSG_ERROR([Couldn't find libudns. Try installing libudns-dev or udns-devel.])])
AC_CHECK_LIB([ev], [ev_loop_destroy], ,[AC_MSG_ERROR([Couldn't find libev. Try installing libev-dev@<:@el@:>@.])])
@@ -0,0 +1,20 @@
--- a/src/obfs/obfs.c
+++ b/src/obfs/obfs.c
@@ -88,7 +88,7 @@ obfs_class *new_obfs_class(const char *p
plugin->client_decode = tls12_ticket_auth_client_decode;
return plugin;
- /*} else if (strcmp(plugin_name, "verify_simple") == 0) {
+ } else if (strcmp(plugin_name, "verify_simple") == 0) {
obfs_class * plugin = (obfs_class*)malloc(sizeof(obfs_class));
plugin->init_data = init_data;
plugin->new_obfs = verify_simple_new_obfs;
@@ -115,7 +115,7 @@ obfs_class *new_obfs_class(const char *p
plugin->client_udp_pre_encrypt = NULL;
plugin->client_udp_post_decrypt = NULL;
- return plugin;*/
+ return plugin;
} else if (strcmp(plugin_name, "auth_sha1") == 0) {
obfs_class *plugin = (obfs_class *) malloc(sizeof(obfs_class));
plugin->init_data = auth_simple_init_data;
@@ -0,0 +1,37 @@
--- a/src/utils.c
+++ b/src/utils.c
@@ -258,8 +258,6 @@ usage()
{
printf("\n");
printf("shadowsocks-libev %s with %s\n\n", VERSION, USING_CRYPTO);
- printf(
- " maintained by Max Lv <max.c.lv@gmail.com> and Linus Yang <laokongzi@gmail.com>\n\n");
printf(" usage:\n\n");
#ifdef MODULE_LOCAL
printf(" ss-local\n");
@@ -299,6 +297,25 @@ usage()
" The default cipher is rc4-md5.\n");
printf("\n");
printf(
+ " -o <obfs> Obfs of your remote server: plain,\n");
+ printf(
+ " http_simple, http_post and tls1.2_ticket_auth.\n");
+ printf(
+ " -g <obfs-param> Obfs-Param of your remote server.\n");
+ printf(
+ " -O <protocol> Protocol of your remote server: origin,\n");
+ printf(
+ " auth_sha1, auth_sha1_v2, auth_sha1_v4,\n");
+ printf(
+ " auth_aes128_md5, auth_aes128_sha1,\n");
+ printf(
+ " auth_chain_a, auth_chain_b, auth_chain_c,\n");
+ printf(
+ " auth_chain_d, auth_chain_e and auth_chain_f.\n");
+ printf(
+ " -G <protocol-param> Protocol-Param of your remote server.\n");
+ printf("\n");
+ printf(
" [-a <user>] Run as another user.\n");
printf(
" [-f <pid_file>] The file path to store pid.\n");
@@ -0,0 +1,20 @@
--- a/src/http.h
+++ b/src/http.h
@@ -29,6 +29,6 @@
#include <stdio.h>
#include "protocol.h"
-const protocol_t *const http_protocol;
+extern const protocol_t *const http_protocol;
#endif
--- a/src/tls.h
+++ b/src/tls.h
@@ -28,6 +28,6 @@
#include "protocol.h"
-const protocol_t *const tls_protocol;
+extern const protocol_t *const tls_protocol;
#endif
@@ -0,0 +1,11 @@
--- a/src/local.c
+++ b/src/local.c
@@ -718,7 +718,7 @@ server_recv_cb(EV_P_ ev_io *w, int reven
ss_free(hostname);
} else {
- strncpy(host, ip, sizeof(ip));
+ strncpy(host, ip, INET6_ADDRSTRLEN);
}
}
@@ -0,0 +1,34 @@
--- a/src/jconf.c
+++ b/src/jconf.c
@@ -259,6 +259,19 @@ read_jconf(const char *file)
conf.server_legacy.obfs = to_string(value);
} else if (strcmp(name, "obfs_param") == 0) { // SSR
conf.server_legacy.obfs_param = to_string(value);
+ } else if (strcmp(name, "mode") == 0) {
+ char *mode_str = to_string(value);
+
+ if (strcmp(mode_str, "tcp_only") == 0)
+ conf.mode = TCP_ONLY;
+ else if (strcmp(mode_str, "tcp_and_udp") == 0)
+ conf.mode = TCP_AND_UDP;
+ else if (strcmp(mode_str, "udp_only") == 0)
+ conf.mode = UDP_ONLY;
+ else
+ LOGI("ignore unknown mode: %s, use tcp_only as fallback",
+ mode_str);
+ ss_free(mode_str);
} else {
match = 0;
}
--- a/src/redir.c
+++ b/src/redir.c
@@ -1252,6 +1252,9 @@ main(int argc, char **argv)
if (user == NULL) {
user = conf->user;
}
+ if (mode == TCP_ONLY) {
+ mode = conf->mode;
+ }
if (mtu == 0) {
mtu = conf->mtu;
}
@@ -0,0 +1,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");
@@ -0,0 +1,479 @@
From 32f944b9a06fb2be4cd50da2434f2fd4b4decede Mon Sep 17 00:00:00 2001
From: sbwml <984419930@qq.com>
Date: Thu, 1 Feb 2024 21:21:56 +0800
Subject: [PATCH] Upgrade PCRE to PCRE2
Signed-off-by: sbwml <984419930@qq.com>
---
configure.ac | 8 +--
m4/pcre.m4 | 152 ------------------------------------------
m4/pcre2.m4 | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/rule.c | 47 ++++++++++---
src/rule.h | 22 +++++--
5 files changed, 238 insertions(+), 172 deletions(-)
delete mode 100644 m4/pcre.m4
create mode 100644 m4/pcre2.m4
--- a/configure.ac
+++ b/configure.ac
@@ -20,10 +20,10 @@ AC_DISABLE_STATIC
AC_DISABLE_SHARED
LT_INIT([dlopen])
-dnl Check for pcre library
-TS_CHECK_PCRE
-if test "x${enable_pcre}" != "xyes"; then
- AC_MSG_ERROR([Cannot find pcre library. Configure --with-pcre=DIR])
+dnl Check for pcre2 library
+TS_CHECK_PCRE2
+if test "x${enable_pcre2}" != "xyes"; then
+ AC_MSG_ERROR([Cannot find pcre2 library. Configure --with-pcre2=DIR])
fi
dnl Checks for using shared libraries from system
--- a/m4/pcre.m4
+++ /dev/null
@@ -1,152 +0,0 @@
-dnl -------------------------------------------------------- -*- autoconf -*-
-dnl Licensed to the Apache Software Foundation (ASF) under one or more
-dnl contributor license agreements. See the NOTICE file distributed with
-dnl this work for additional information regarding copyright ownership.
-dnl The ASF licenses this file to You under the Apache License, Version 2.0
-dnl (the "License"); you may not use this file except in compliance with
-dnl the License. You may obtain a copy of the License at
-dnl
-dnl http://www.apache.org/licenses/LICENSE-2.0
-dnl
-dnl Unless required by applicable law or agreed to in writing, software
-dnl distributed under the License is distributed on an "AS IS" BASIS,
-dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-dnl See the License for the specific language governing permissions and
-dnl limitations under the License.
-
-dnl
-dnl TS_ADDTO(variable, value)
-dnl
-dnl Add value to variable
-dnl
-AC_DEFUN([TS_ADDTO], [
- if test "x$$1" = "x"; then
- test "x$verbose" = "xyes" && echo " setting $1 to \"$2\""
- $1="$2"
- else
- ats_addto_bugger="$2"
- for i in $ats_addto_bugger; do
- ats_addto_duplicate="0"
- for j in $$1; do
- if test "x$i" = "x$j"; then
- ats_addto_duplicate="1"
- break
- fi
- done
- if test $ats_addto_duplicate = "0"; then
- test "x$verbose" = "xyes" && echo " adding \"$i\" to $1"
- $1="$$1 $i"
- fi
- done
- fi
-])dnl
-
-dnl
-dnl TS_ADDTO_RPATH(path)
-dnl
-dnl Adds path to variable with the '-rpath' directive.
-dnl
-AC_DEFUN([TS_ADDTO_RPATH], [
- AC_MSG_NOTICE([adding $1 to RPATH])
- TS_ADDTO(LIBTOOL_LINK_FLAGS, [-R$1])
-])dnl
-
-dnl
-dnl pcre.m4: Trafficserver's pcre autoconf macros
-dnl
-
-dnl
-dnl TS_CHECK_PCRE: look for pcre libraries and headers
-dnl
-AC_DEFUN([TS_CHECK_PCRE], [
-enable_pcre=no
-AC_ARG_WITH(pcre, [AC_HELP_STRING([--with-pcre=DIR],[use a specific pcre library])],
-[
- if test "x$withval" != "xyes" && test "x$withval" != "x"; then
- pcre_base_dir="$withval"
- if test "$withval" != "no"; then
- enable_pcre=yes
- case "$withval" in
- *":"*)
- pcre_include="`echo $withval |sed -e 's/:.*$//'`"
- pcre_ldflags="`echo $withval |sed -e 's/^.*://'`"
- AC_MSG_CHECKING(checking for pcre includes in $pcre_include libs in $pcre_ldflags )
- ;;
- *)
- pcre_include="$withval/include"
- pcre_ldflags="$withval/lib"
- AC_MSG_CHECKING(checking for pcre includes in $withval)
- ;;
- esac
- fi
- fi
-],
-[
- AC_CHECK_PROG(PCRE_CONFIG, pcre-config, pcre-config)
- if test "x$PCRE_CONFIG" != "x"; then
- enable_pcre=yes
- pcre_base_dir="`$PCRE_CONFIG --prefix`"
- pcre_include="`$PCRE_CONFIG --cflags | sed -es/-I//`"
- pcre_ldflags="`$PCRE_CONFIG --libs | sed -es/-lpcre// -es/-L//`"
- fi
-])
-
-if test "x$pcre_base_dir" = "x"; then
- AC_MSG_CHECKING([for pcre location])
- AC_CACHE_VAL(ats_cv_pcre_dir,[
- for dir in /usr/local /usr ; do
- if test -d $dir && ( test -f $dir/include/pcre.h || test -f $dir/include/pcre/pcre.h ); then
- ats_cv_pcre_dir=$dir
- break
- fi
- done
- ])
- pcre_base_dir=$ats_cv_pcre_dir
- if test "x$pcre_base_dir" = "x"; then
- enable_pcre=no
- AC_MSG_RESULT([not found])
- else
- enable_pcre=yes
- pcre_include="$pcre_base_dir/include"
- pcre_ldflags="$pcre_base_dir/lib"
- AC_MSG_RESULT([$pcre_base_dir])
- fi
-else
- AC_MSG_CHECKING(for pcre headers in $pcre_include)
- if test -d $pcre_include && test -d $pcre_ldflags && ( test -f $pcre_include/pcre.h || test -f $pcre_include/pcre/pcre.h ); then
- AC_MSG_RESULT([ok])
- else
- AC_MSG_RESULT([not found])
- fi
-fi
-
-pcreh=0
-pcre_pcreh=0
-if test "$enable_pcre" != "no"; then
- saved_ldflags=$LDFLAGS
- saved_cppflags=$CFLAGS
- pcre_have_headers=0
- pcre_have_libs=0
- if test "$pcre_base_dir" != "/usr"; then
- TS_ADDTO(CFLAGS, [-I${pcre_include}])
- TS_ADDTO(CFLAGS, [-DPCRE_STATIC])
- TS_ADDTO(LDFLAGS, [-L${pcre_ldflags}])
- TS_ADDTO_RPATH(${pcre_ldflags})
- fi
- AC_SEARCH_LIBS([pcre_exec], [pcre], [pcre_have_libs=1])
- if test "$pcre_have_libs" != "0"; then
- AC_CHECK_HEADERS(pcre.h, [pcre_have_headers=1])
- AC_CHECK_HEADERS(pcre/pcre.h, [pcre_have_headers=1])
- fi
- if test "$pcre_have_headers" != "0"; then
- AC_DEFINE(HAVE_LIBPCRE,1,[Compiling with pcre support])
- AC_SUBST(LIBPCRE, [-lpcre])
- else
- enable_pcre=no
- CFLAGS=$saved_cppflags
- LDFLAGS=$saved_ldflags
- fi
-fi
-AC_SUBST(pcreh)
-AC_SUBST(pcre_pcreh)
-])
--- /dev/null
+++ b/m4/pcre2.m4
@@ -0,0 +1,181 @@
+dnl -------------------------------------------------------- -*- autoconf -*-
+dnl Licensed to the Apache Software Foundation (ASF) under one or more
+dnl contributor license agreements. See the NOTICE file distributed with
+dnl this work for additional information regarding copyright ownership.
+dnl The ASF licenses this file to You under the Apache License, Version 2.0
+dnl (the "License"); you may not use this file except in compliance with
+dnl the License. You may obtain a copy of the License at
+dnl
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
+
+dnl Modified by Syrone Wong <wong.syrone@gmail.com> to support pcre2 8bit variant only
+
+dnl
+dnl TS_ADDTO(variable, value)
+dnl
+dnl Add value to variable
+dnl
+AC_DEFUN([TS_ADDTO], [
+ if test "x$$1" = "x"; then
+ test "x$verbose" = "xyes" && echo " setting $1 to \"$2\""
+ $1="$2"
+ else
+ ats_addto_bugger="$2"
+ for i in $ats_addto_bugger; do
+ ats_addto_duplicate="0"
+ for j in $$1; do
+ if test "x$i" = "x$j"; then
+ ats_addto_duplicate="1"
+ break
+ fi
+ done
+ if test $ats_addto_duplicate = "0"; then
+ test "x$verbose" = "xyes" && echo " adding \"$i\" to $1"
+ $1="$$1 $i"
+ fi
+ done
+ fi
+])dnl
+
+dnl
+dnl TS_ADDTO_RPATH(path)
+dnl
+dnl Adds path to variable with the '-rpath' directive.
+dnl
+AC_DEFUN([TS_ADDTO_RPATH], [
+ AC_MSG_NOTICE([adding $1 to RPATH])
+ TS_ADDTO(LIBTOOL_LINK_FLAGS, [-R$1])
+])dnl
+
+dnl
+dnl pcre2.m4: Trafficserver's pcre2 autoconf macros
+dnl
+
+dnl
+dnl TS_CHECK_PCRE2: look for pcre2 libraries and headers
+dnl
+AC_DEFUN([TS_CHECK_PCRE2], [
+enable_pcre2=no
+AC_ARG_WITH(pcre2, [AC_HELP_STRING([--with-pcre2=DIR],[use a specific pcre2 library])],
+[
+ if test "x$withval" != "xyes" && test "x$withval" != "x"; then
+ pcre2_base_dir="$withval"
+ if test "$withval" != "no"; then
+ enable_pcre2=yes
+ case "$withval" in
+ *":"*)
+ pcre2_include="`echo $withval |sed -e 's/:.*$//'`"
+ pcre2_ldflags="`echo $withval |sed -e 's/^.*://'`"
+ AC_MSG_CHECKING(checking for pcre2 includes in $pcre2_include libs in $pcre2_ldflags )
+ ;;
+ *)
+ pcre2_include="$withval/include"
+ pcre2_ldflags="$withval/lib"
+ AC_MSG_CHECKING(checking for pcre2 includes in $withval)
+ ;;
+ esac
+ fi
+ fi
+],
+[
+ AC_CHECK_PROG(PCRE2_CONFIG, pcre2-config, pcre2-config)
+ if test "x$PCRE2_CONFIG" != "x"; then
+ enable_pcre2=yes
+ pcre2_base_dir="`$PCRE2_CONFIG --prefix`"
+ pcre2_include="`$PCRE2_CONFIG --cflags | sed -es/-I//`"
+ pcre2_ldflags="`$PCRE2_CONFIG --libs8 | sed -es/-lpcre2-8// -es/-L//`"
+ fi
+])
+
+if test "x$pcre2_base_dir" = "x"; then
+ AC_MSG_CHECKING([for pcre2 location])
+ AC_CACHE_VAL(ats_cv_pcre2_dir,[
+ for dir in /usr/local /usr ; do
+ if test -d $dir && ( test -f $dir/include/pcre2.h || test -f $dir/include/pcre2/pcre2.h ); then
+ ats_cv_pcre2_dir=$dir
+ break
+ fi
+ done
+ ])
+ pcre2_base_dir=$ats_cv_pcre2_dir
+ if test "x$pcre2_base_dir" = "x"; then
+ enable_pcre2=no
+ AC_MSG_RESULT([not found])
+ else
+ enable_pcre2=yes
+ pcre2_include="$pcre2_base_dir/include"
+ pcre2_ldflags="$pcre2_base_dir/lib"
+ AC_MSG_RESULT([$pcre2_base_dir])
+ fi
+else
+ AC_MSG_CHECKING(for pcre2 headers in $pcre2_include)
+ if test -d $pcre2_include && test -d $pcre2_ldflags && ( test -f $pcre2_include/pcre2.h || test -f $pcre2_include/pcre2/pcre2.h ); then
+ AC_MSG_RESULT([ok])
+ else
+ AC_MSG_RESULT([not found])
+ fi
+fi
+
+pcre2h=0
+pcre2_pcre2h=0
+if test "$enable_pcre2" != "no"; then
+ saved_ldflags=$LDFLAGS
+ saved_cppflags=$CFLAGS
+ pcre2_have_headers=0
+ pcre2_have_libs=0
+ if test "$pcre2_base_dir" != "/usr"; then
+ TS_ADDTO(CFLAGS, [-I${pcre2_include}])
+ TS_ADDTO(CFLAGS, [-DPCRE2_STATIC])
+ TS_ADDTO(LDFLAGS, [-L${pcre2_ldflags}])
+ TS_ADDTO_RPATH(${pcre2_ldflags})
+ fi
+ AC_SEARCH_LIBS([pcre2_match_8], [pcre2-8], [pcre2_have_libs=1])
+ if test "$pcre2_have_libs" != "0"; then
+ AC_MSG_CHECKING([pcre2.h])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
+ ]],
+ [[
+ ]]
+ )],
+ [pcre2_have_headers=1
+ AC_MSG_RESULT([ok])],
+ [AC_MSG_RESULT([not found])]
+ )
+
+ AC_MSG_CHECKING([pcre2/pcre2.h])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2/pcre2.h>
+ ]],
+ [[
+ ]]
+ )],
+ [pcre2_have_headers=1
+ AC_MSG_RESULT([ok])],
+ [AC_MSG_RESULT([not found])]
+ )
+ fi
+ if test "$pcre2_have_headers" != "0"; then
+ AC_DEFINE(HAVE_LIBPCRE2,1,[Compiling with pcre2 support])
+ AC_SUBST(LIBPCRE2, [-lpcre2-8])
+ else
+ enable_pcre2=no
+ CFLAGS=$saved_cppflags
+ LDFLAGS=$saved_ldflags
+ fi
+fi
+AC_SUBST(pcre2h)
+AC_SUBST(pcre2_pcre2h)
+])
--- a/src/rule.c
+++ b/src/rule.c
@@ -82,14 +82,28 @@ int
init_rule(rule_t *rule)
{
if (rule->pattern_re == NULL) {
- const char *reerr;
- int reerroffset;
+ int errornumber;
+ PCRE2_SIZE erroroffset;
+ rule->pattern_re = pcre2_compile(
+ (PCRE2_SPTR)rule->pattern, /* the pattern */
+ PCRE2_ZERO_TERMINATED, /* indicates pattern is zero-terminated */
+ 0, /* default options */
+ &errornumber, /* for error number */
+ &erroroffset, /* for error offset */
+ NULL); /* use default compile context */
- rule->pattern_re =
- pcre_compile(rule->pattern, 0, &reerr, &reerroffset, NULL);
if (rule->pattern_re == NULL) {
- LOGE("Regex compilation of \"%s\" failed: %s, offset %d",
- rule->pattern, reerr, reerroffset);
+ PCRE2_UCHAR errbuffer[512];
+ pcre2_get_error_message(errornumber, errbuffer, sizeof(errbuffer));
+ LOGE("PCRE2 regex compilation failed at offset %d: %s\n", (int)erroroffset,
+ errbuffer);
+ return 0;
+ }
+
+ rule->pattern_re_match_data = pcre2_match_data_create_from_pattern(rule->pattern_re, NULL);
+
+ if (rule->pattern_re_match_data == NULL) {
+ ERROR("PCRE2: the memory for the block could not be obtained");
return 0;
}
}
@@ -109,8 +123,15 @@ lookup_rule(const struct cork_dllist *ru
cork_dllist_foreach_void(rules, curr, next) {
rule_t *rule = cork_container_of(curr, rule_t, entries);
- if (pcre_exec(rule->pattern_re, NULL,
- name, name_len, 0, 0, NULL, 0) >= 0)
+ if (pcre2_match(
+ rule->pattern_re, /* the compiled pattern */
+ (PCRE2_SPTR)name, /* the subject string */
+ name_len, /* the length of the subject */
+ 0, /* start at offset 0 in the subject */
+ 0, /* default options */
+ rule->pattern_re_match_data, /* block for storing the result */
+ NULL /* use default match context */
+ ) >= 0)
return rule;
}
@@ -131,7 +152,13 @@ free_rule(rule_t *rule)
return;
ss_free(rule->pattern);
- if (rule->pattern_re != NULL)
- pcre_free(rule->pattern_re);
+ if (rule->pattern_re != NULL) {
+ pcre2_code_free(rule->pattern_re); /* data and the compiled pattern. */
+ rule->pattern_re = NULL;
+ }
+ if (rule->pattern_re_match_data != NULL) {
+ pcre2_match_data_free(rule->pattern_re_match_data); /* Release memory used for the match */
+ rule->pattern_re_match_data = NULL;
+ }
ss_free(rule);
}
--- a/src/rule.h
+++ b/src/rule.h
@@ -33,17 +33,27 @@
#include <libcork/ds.h>
-#ifdef HAVE_PCRE_H
-#include <pcre.h>
-#elif HAVE_PCRE_PCRE_H
-#include <pcre/pcre.h>
-#endif
+/*
+ * The PCRE2_CODE_UNIT_WIDTH macro must be defined before including pcre2.h.
+ * For a program that uses only one code unit width, setting it to 8, 16, or 32
+ * makes it possible to use generic function names such as pcre2_compile(). Note
+ * that just changing 8 to 16 (for example) is not sufficient to convert this
+ * program to process 16-bit characters. Even in a fully 16-bit environment, where
+ * string-handling functions such as strcmp() and printf() work with 16-bit
+ * characters, the code for handling the table of named substrings will still need
+ * to be modified.
+ */
+/* we only need to support ASCII chartable, thus set it to 8 */
+#define PCRE2_CODE_UNIT_WIDTH 8
+
+#include <pcre2.h>
typedef struct rule {
char *pattern;
/* Runtime fields */
- pcre *pattern_re;
+ pcre2_code *pattern_re;
+ pcre2_match_data *pattern_re_match_data;
struct cork_dllist_item entries;
} rule_t;