diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a922e13 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "gost"] + path = gost + url = https://github.com/segfault-bilibili/gost.git diff --git a/build.sh b/build.sh index 628d41b..30de019 100644 --- a/build.sh +++ b/build.sh @@ -3,6 +3,7 @@ NDK_VERSION_IF_MISSING=r23b GOST_VERSION=2.11.1 GOLANG_VERSION=1.17.6 cd $( cd "$( dirname "$0" )" && pwd ) +git submodule update --init --recursive if [ ! -e build ] then mkdir build @@ -18,13 +19,9 @@ fi export PATH=$PWD/go/bin:$PATH export GOROOT=$PWD/go go version -if [ ! -e gost ] +if [ ! -e gost ] && [ -d ../gost ] then -curl "https://github.com/ginuerzh/gost/archive/v$GOST_VERSION.tar.gz" -L | tar -zx || exit $? -mv gost-$GOST_VERSION gost -cd gost -patch -p1 -r . < ../../gost.patch -cd .. +mv -v ../gost . fi IS_NDK_MISSING=true if find $ANDROID_NDK_ROOT | grep clang$ diff --git a/gost b/gost new file mode 160000 index 0000000..520ecf7 --- /dev/null +++ b/gost @@ -0,0 +1 @@ +Subproject commit 520ecf7f69345c7bcacb198f0d6dc6c01f01584d diff --git a/gost.patch b/gost.patch deleted file mode 100644 index 2aafa7c..0000000 --- a/gost.patch +++ /dev/null @@ -1,212 +0,0 @@ -diff -ruN gost.back/cmd/gost/main.go gost/cmd/gost/main.go ---- gost.back/cmd/gost/main.go 2020-03-14 15:01:10.651935500 +0800 -+++ gost/cmd/gost/main.go 2020-03-14 16:17:45.537385600 +0800 -@@ -8,10 +8,12 @@ - "net/http" - "os" - "runtime" -+ "strings" - - _ "net/http/pprof" - - "github.com/ginuerzh/gost" -+ "github.com/ginuerzh/gost/utils" - "github.com/go-log/log" - ) - -@@ -27,13 +29,25 @@ - - var ( - printVersion bool -+ fastOpen bool - ) -+ localHost := os.Getenv("SS_LOCAL_HOST") -+ localPort := os.Getenv("SS_LOCAL_PORT") -+ pluginOptions := os.Getenv("SS_PLUGIN_OPTIONS") -+ pluginOptions = strings.ReplaceAll(pluginOptions, "#SS_HOST", os.Getenv("SS_REMOTE_HOST")) -+ pluginOptions = strings.ReplaceAll(pluginOptions, "#SS_PORT", os.Getenv("SS_REMOTE_PORT")) -+ -+ os.Args = append(os.Args, "-L") -+ os.Args = append(os.Args, fmt.Sprintf("ss+tcp://rc4-md5:gost@[%s]:%s", localHost, localPort)) -+ os.Args = append(os.Args, strings.Split(pluginOptions, " ")...) - - flag.Var(&baseCfg.route.ChainNodes, "F", "forward address, can make a forward chain") - flag.Var(&baseCfg.route.ServeNodes, "L", "listen address, can listen on multiple ports (required)") - flag.StringVar(&configureFile, "C", "", "configure file") - flag.BoolVar(&baseCfg.Debug, "D", false, "enable debug log") -- flag.BoolVar(&printVersion, "V", false, "print version") -+ flag.BoolVar(&utils.VpnMode, "V", false, "VPN Mode") -+ flag.BoolVar(&fastOpen, "fast-open", false, "fast Open TCP") -+ flag.BoolVar(&printVersion, "PV", false, "print version") - if pprofEnabled { - flag.StringVar(&pprofAddr, "P", ":6060", "profiling HTTP server address") - } -@@ -45,6 +59,12 @@ - os.Exit(0) - } - -+ if localHost == "" || localPort == "" { -+ fmt.Fprintln(os.Stderr, "Can only be used in the shadowsocks plugin.") -+ os.Exit(1) -+ } -+ utils.Init() -+ - if configureFile != "" { - _, err := parseBaseConfig(configureFile) - if err != nil { -diff -ruN gost.back/utils/utils.go gost/utils/utils.go ---- gost.back/utils/utils.go 1970-01-01 08:00:00.000000000 +0800 -+++ gost/utils/utils.go 2020-03-14 16:16:52.766185200 +0800 -@@ -0,0 +1,7 @@ -+// +build !android -+ -+package utils -+ -+var VpnMode bool -+ -+func Init() {} -\ No newline at end of file -diff -ruN gost.back/utils/utils_android.go gost/utils/utils_android.go ---- gost.back/utils/utils_android.go 1970-01-01 08:00:00.000000000 +0800 -+++ gost/utils/utils_android.go 2020-03-14 16:16:30.964564900 +0800 -@@ -0,0 +1,140 @@ -+// +build android -+ -+package utils -+ -+/* -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define ANCIL_FD_BUFFER(n) \ -+ struct { \ -+ struct cmsghdr h; \ -+ int fd[n]; \ -+ } -+ -+int -+ancil_send_fds_with_buffer(int sock, const int *fds, unsigned n_fds, void *buffer) -+{ -+ struct msghdr msghdr; -+ char nothing = '!'; -+ struct iovec nothing_ptr; -+ struct cmsghdr *cmsg; -+ int i; -+ -+ nothing_ptr.iov_base = ¬hing; -+ nothing_ptr.iov_len = 1; -+ msghdr.msg_name = NULL; -+ msghdr.msg_namelen = 0; -+ msghdr.msg_iov = ¬hing_ptr; -+ msghdr.msg_iovlen = 1; -+ msghdr.msg_flags = 0; -+ msghdr.msg_control = buffer; -+ msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int) * n_fds; -+ cmsg = CMSG_FIRSTHDR(&msghdr); -+ cmsg->cmsg_len = msghdr.msg_controllen; -+ cmsg->cmsg_level = SOL_SOCKET; -+ cmsg->cmsg_type = SCM_RIGHTS; -+ for(i = 0; i < n_fds; i++) -+ ((int *)CMSG_DATA(cmsg))[i] = fds[i]; -+ return(sendmsg(sock, &msghdr, 0) >= 0 ? 0 : -1); -+} -+ -+int -+ancil_send_fd(int sock, int fd) -+{ -+ ANCIL_FD_BUFFER(1) buffer; -+ -+ return(ancil_send_fds_with_buffer(sock, &fd, 1, &buffer)); -+} -+ -+void -+set_timeout(int sock) -+{ -+ struct timeval tv; -+ tv.tv_sec = 3; -+ tv.tv_usec = 0; -+ setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)); -+ setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval)); -+} -+ -+*/ -+import "C" -+ -+import ( -+ "context" -+ "log" -+ "net" -+ "syscall" -+) -+ -+var VpnMode bool -+ -+func ControlOnConnSetup(network string, address string, c syscall.RawConn) error { -+ if VpnMode { -+ fn := func(s uintptr) { -+ fd := int(s) -+ path := "protect_path" -+ -+ socket, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) -+ if err != nil { -+ log.Println(err) -+ return -+ } -+ -+ defer syscall.Close(socket) -+ -+ C.set_timeout(C.int(socket)) -+ -+ err = syscall.Connect(socket, &syscall.SockaddrUnix{Name: path}) -+ if err != nil { -+ log.Println(err) -+ return -+ } -+ -+ C.ancil_send_fd(C.int(socket), C.int(fd)) -+ -+ dummy := []byte{1} -+ n, err := syscall.Read(socket, dummy) -+ if err != nil { -+ log.Println(err) -+ return -+ } -+ if n != 1 { -+ log.Println("Failed to protect fd: ", fd) -+ return -+ } -+ } -+ -+ if err := c.Control(fn); err != nil { -+ return err -+ } -+ } -+ -+ return nil -+} -+ -+func Init() { -+ log.Printf("Android Utils Init. VpnMode: %v", VpnMode) -+ net.DefaultResolver = &net.Resolver{Dial: func(ctx context.Context, network, address string) (net.Conn, error) { -+ log.Printf("DefaultResolver address %v modify to %v", address, "119.29.29.29:53") -+ d := net.Dialer{} -+ return d.DialContext(ctx, network, "119.29.29.29:53") -+ }, PreferGo: true} -+ if VpnMode { -+ log.Printf("VpnMode Hook Init.") -+ net.ListenUDPListenConfigHook = func(c *net.ListenConfig) { -+ log.Printf("DialContextDialerHook %v", c) -+ c.Control = ControlOnConnSetup -+ } -+ net.DialContextDialerHook = func(d *net.Dialer) { -+ log.Printf("DialContextDialerHook %v", d) -+ d.Control = ControlOnConnSetup -+ } -+ } -+}