Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock

Please unblock shadowsocks-libev 3.2.5+ds-1. Current version of
shadowsocks-libev (3.2.4) in Testing has some known bugs for port
parser and ipv6 support and upstream released another bugfix version
(3.2.5).

The 3.2.5+ds-1 version is currently in Debian Unstable now and it
builds correctly on all architectures.

The full debdiff is provided in the attachment. The brief changelog is
provided here:

+shadowsocks-libev (3.2.5+ds-1) unstable; urgency=high
+
+  * New upstream release: v3.2.5
+    + Fix a bug in port parser.
+  * debian/patches: Cherry-pick several important upstream patches:
+    + backport/0001: Fix upstream issue #3214 that make the plugin
+      crash.
+    + backport/0002: Fix and refine ipv6only support.
+
+ -- Boyuan Yang <by...@debian.org>  Wed, 20 Mar 2019 11:35:43 -0400

--
Thanks,
Boyuan Yang
diff -Nru shadowsocks-libev-3.2.4+ds/Changes shadowsocks-libev-3.2.5+ds/Changes
--- shadowsocks-libev-3.2.4+ds/Changes	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/Changes	2019-03-20 11:30:51.000000000 -0400
@@ -1,3 +1,9 @@
+shadowsocks-libev (3.2.5-1) unstable; urgency=medium
+
+  * Fix a bug of port parser.
+
+ -- Max Lv <max.c...@gmail.com>  Sat, 09 Mar 2019 18:54:36 +0800
+
 shadowsocks-libev (3.2.4-1) unstable; urgency=medium
 
   * Fix a crash with MinGW.
diff -Nru shadowsocks-libev-3.2.4+ds/cmake/configure.cmake shadowsocks-libev-3.2.5+ds/cmake/configure.cmake
--- shadowsocks-libev-3.2.4+ds/cmake/configure.cmake	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/cmake/configure.cmake	2019-03-20 11:30:51.000000000 -0400
@@ -18,6 +18,9 @@
 set(CONNECT_IN_PROGRESS "EINPROGRESS")
 set(CONNECT_IN_PROGRESS "EINPROGRESS" CACHE STRING "")
 
+if (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+    set(CMAKE_REQUIRED_INCLUDES "/usr/local/include" "/usr/include")
+endif ()
 
 check_include_files(dlfcn.h HAVE_DLFCN_H)
 check_include_files(ev.h HAVE_EV_H)
diff -Nru shadowsocks-libev-3.2.4+ds/CMakeLists.txt shadowsocks-libev-3.2.5+ds/CMakeLists.txt
--- shadowsocks-libev-3.2.4+ds/CMakeLists.txt	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/CMakeLists.txt	2019-03-20 11:30:51.000000000 -0400
@@ -1,8 +1,8 @@
 cmake_minimum_required(VERSION 3.2)
 
 set(PROJECT_NAME shadowsocks-libev)
-set(RELEASE_DATE 2019-02-26)
-set(PROJECT_VERSION "3.2.4")
+set(RELEASE_DATE 2019-03-09)
+set(PROJECT_VERSION "3.2.5")
 set(PROJECT_DESC "a lightweight secured socks5 proxy")
 set(PROJECT_URL "https://shadowsocks.org";)
 set(PROJECT_ISSUES_URL "https://github.com/shadowsocks/shadowsocks-libev";)
diff -Nru shadowsocks-libev-3.2.4+ds/configure.ac shadowsocks-libev-3.2.5+ds/configure.ac
--- shadowsocks-libev-3.2.4+ds/configure.ac	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/configure.ac	2019-03-20 11:30:51.000000000 -0400
@@ -2,7 +2,7 @@
 dnl Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.67])
-AC_INIT([shadowsocks-libev], [3.2.4], [max.c...@gmail.com])
+AC_INIT([shadowsocks-libev], [3.2.5], [max.c...@gmail.com])
 AC_CONFIG_SRCDIR([src/crypto.c])
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_AUX_DIR(auto)
diff -Nru shadowsocks-libev-3.2.4+ds/debian/changelog shadowsocks-libev-3.2.5+ds/debian/changelog
--- shadowsocks-libev-3.2.4+ds/debian/changelog	2019-03-01 11:31:45.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/debian/changelog	2019-03-20 11:35:43.000000000 -0400
@@ -1,3 +1,14 @@
+shadowsocks-libev (3.2.5+ds-1) unstable; urgency=high
+
+  * New upstream release: v3.2.5
+    + Fix a bug in port parser.
+  * debian/patches: Cherry-pick several important upstream patches:
+    + backport/0001: Fix upstream issue #3214 that make the plugin
+      crash.
+    + backport/0002: Fix and refine ipv6only support.
+
+ -- Boyuan Yang <by...@debian.org>  Wed, 20 Mar 2019 11:35:43 -0400
+
 shadowsocks-libev (3.2.4+ds-1) unstable; urgency=medium
 
   * New upstream release: v3.2.4
diff -Nru shadowsocks-libev-3.2.4+ds/debian/patches/backport/0001-Fix-2314.patch shadowsocks-libev-3.2.5+ds/debian/patches/backport/0001-Fix-2314.patch
--- shadowsocks-libev-3.2.4+ds/debian/patches/backport/0001-Fix-2314.patch	1969-12-31 19:00:00.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/debian/patches/backport/0001-Fix-2314.patch	2019-03-20 11:35:22.000000000 -0400
@@ -0,0 +1,23 @@
+From: Max Lv <max.c...@gmail.com>
+Date: Sun, 10 Mar 2019 07:21:55 +0800
+Subject: Fix #2314
+
+Applied-Upstream: https://github.com/shadowsocks/shadowsocks-libev/commit/1a77023777e97d34726d7b391c0403f2a21ab6c0
+
+---
+ src/netutils.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/netutils.c b/src/netutils.c
+index f89e971..6bc14c7 100644
+--- a/src/netutils.c
++++ b/src/netutils.c
+@@ -295,6 +295,8 @@ is_ipv6only(ss_addr_t *servers, size_t server_num)
+             if (ip.version != 6) {
+                 return 0;
+             }
++        } else {
++            return 0;
+         }
+     }
+     return 1;
diff -Nru shadowsocks-libev-3.2.4+ds/debian/patches/backport/0001-Refine-ipv6-only-handling.-2300.patch shadowsocks-libev-3.2.5+ds/debian/patches/backport/0001-Refine-ipv6-only-handling.-2300.patch
--- shadowsocks-libev-3.2.4+ds/debian/patches/backport/0001-Refine-ipv6-only-handling.-2300.patch	2019-03-01 11:31:34.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/debian/patches/backport/0001-Refine-ipv6-only-handling.-2300.patch	1969-12-31 19:00:00.000000000 -0500
@@ -1,210 +0,0 @@
-From: Max Lv <max.c...@gmail.com>
-Date: Fri, 1 Mar 2019 07:32:25 +0800
-Subject: Refine ipv6 only handling. #2300
-
----
- src/jconf.c    |  1 +
- src/jconf.h    |  5 -----
- src/local.c    |  6 +++++-
- src/manager.c  |  2 +-
- src/netutils.c | 16 ++++++++++++++++
- src/netutils.h |  7 +++++++
- src/redir.c    |  6 +++++-
- src/server.c   | 15 +++++++++++----
- src/tunnel.c   |  6 +++++-
- 9 files changed, 51 insertions(+), 13 deletions(-)
-
-diff --git a/src/jconf.c b/src/jconf.c
-index 5421d18..c03854a 100644
---- a/src/jconf.c
-+++ b/src/jconf.c
-@@ -25,6 +25,7 @@
- #include <string.h>
- #include <time.h>
- 
-+#include "netutils.h"
- #include "utils.h"
- #include "jconf.h"
- #include "json.h"
-diff --git a/src/jconf.h b/src/jconf.h
-index bf41b05..06dbf92 100644
---- a/src/jconf.h
-+++ b/src/jconf.h
-@@ -43,11 +43,6 @@
- #define TCP_AND_UDP  1
- #define UDP_ONLY     3
- 
--typedef struct {
--    char *host;
--    char *port;
--} ss_addr_t;
--
- typedef struct {
-     char *port;
-     char *password;
-diff --git a/src/local.c b/src/local.c
-index d882b45..15a583a 100644
---- a/src/local.c
-+++ b/src/local.c
-@@ -1707,7 +1707,11 @@ main(int argc, char **argv)
-             FATAL("failed to find a free port");
-         }
-         snprintf(tmp_port, 8, "%d", port);
--        plugin_host = "127.0.0.1";
-+        if (is_ipv6only(remote_addr, remote_num)) {
-+            plugin_host = "::1";
-+        } else {
-+            plugin_host = "127.0.0.1";
-+        }
-         plugin_port = tmp_port;
- 
- #ifdef __MINGW32__
-diff --git a/src/manager.c b/src/manager.c
-index 82a5ab2..16af841 100644
---- a/src/manager.c
-+++ b/src/manager.c
-@@ -58,8 +58,8 @@
- 
- #include "json.h"
- #include "utils.h"
--#include "manager.h"
- #include "netutils.h"
-+#include "manager.h"
- 
- #ifndef BUF_SIZE
- #define BUF_SIZE 65535
-diff --git a/src/netutils.c b/src/netutils.c
-index 9653659..f89e971 100644
---- a/src/netutils.c
-+++ b/src/netutils.c
-@@ -283,3 +283,19 @@ validate_hostname(const char *hostname, const int hostname_len)
- 
-     return 1;
- }
-+
-+int
-+is_ipv6only(ss_addr_t *servers, size_t server_num)
-+{
-+    struct cork_ip ip;
-+    int i;
-+    for (i = 0; i < server_num; i++)
-+    {
-+        if (cork_ip_init(&ip, servers[i].host) != -1) {
-+            if (ip.version != 6) {
-+                return 0;
-+            }
-+        }
-+    }
-+    return 1;
-+}
-diff --git a/src/netutils.h b/src/netutils.h
-index 1565dcf..f7f6dc6 100644
---- a/src/netutils.h
-+++ b/src/netutils.h
-@@ -52,6 +52,11 @@
- #endif
- #endif
- 
-+typedef struct {
-+    char *host;
-+    char *port;
-+} ss_addr_t;
-+
- /* MPTCP_ENABLED setsockopt values for kernel 4 & 3, best behaviour to be independant of kernel version is to test from newest to the latest values */
- #ifndef MPTCP_ENABLED
- static const char mptcp_enabled_values[] = { 42, 26, 0 };
-@@ -103,4 +108,6 @@ int sockaddr_cmp_addr(struct sockaddr_storage *addr1,
- 
- int validate_hostname(const char *hostname, const int hostname_len);
- 
-+int is_ipv6only(ss_addr_t *servers, size_t server_num);
-+
- #endif
-diff --git a/src/redir.c b/src/redir.c
-index 4133974..be9da07 100644
---- a/src/redir.c
-+++ b/src/redir.c
-@@ -1065,7 +1065,11 @@ main(int argc, char **argv)
-             FATAL("failed to find a free port");
-         }
-         snprintf(tmp_port, 8, "%d", port);
--        plugin_host = "127.0.0.1";
-+        if (is_ipv6only(remote_addr, remote_num)) {
-+            plugin_host = "::1";
-+        } else {
-+            plugin_host = "127.0.0.1";
-+        }
-         plugin_port = tmp_port;
- 
-         LOGI("plugin \"%s\" enabled", plugin);
-diff --git a/src/server.c b/src/server.c
-index 5d80739..eced490 100644
---- a/src/server.c
-+++ b/src/server.c
-@@ -404,8 +404,8 @@ create_and_bind(const char *host, const char *port, int mptcp)
-         }
- 
-         if (rp->ai_family == AF_INET6) {
--            int ipv6only = host ? 1 : 0;
--            setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, sizeof(ipv6only));
-+            int opt = host ? 1 : 0;
-+            setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
-         }
- 
-         int opt = 1;
-@@ -1607,6 +1607,7 @@ main(int argc, char **argv)
- 
-     char *server_port = NULL;
-     char *plugin_opts = NULL;
-+    char *plugin_host = NULL;
-     char *plugin_port = NULL;
-     char tmp_port[8];
- 
-@@ -1834,6 +1835,12 @@ main(int argc, char **argv)
-         exit(EXIT_FAILURE);
-     }
- 
-+    if (is_ipv6only(server_addr, server_num)) {
-+        plugin_host = "::1";
-+    } else {
-+        plugin_host = "127.0.0.1";
-+    }
-+
-     remote_port = server_port;
- 
- #ifdef __MINGW32__
-@@ -1991,7 +1998,7 @@ main(int argc, char **argv)
-         }
- 
-         int err = start_plugin(plugin, plugin_opts, server_str,
--                               plugin_port, "127.0.0.1", server_port,
-+                               plugin_port, plugin_host, server_port,
- #ifdef __MINGW32__
-                                plugin_watcher.port,
- #endif
-@@ -2013,7 +2020,7 @@ main(int argc, char **argv)
-             const char *port = server_addr[i].port ? server_addr[i].port : server_port;
- 
-             if (plugin != NULL) {
--                host = "127.0.0.1";
-+                host = plugin_host;
-             }
- 
-             if (host && ss_is_ipv6addr(host))
-diff --git a/src/tunnel.c b/src/tunnel.c
-index f6c2a90..7a33d33 100644
---- a/src/tunnel.c
-+++ b/src/tunnel.c
-@@ -1114,7 +1114,11 @@ main(int argc, char **argv)
-             FATAL("failed to find a free port");
-         }
-         snprintf(tmp_port, 8, "%d", port);
--        plugin_host = "127.0.0.1";
-+        if (is_ipv6only(remote_addr, remote_num)) {
-+            plugin_host = "::1";
-+        } else {
-+            plugin_host = "127.0.0.1";
-+        }
-         plugin_port = tmp_port;
- 
- #ifdef __MINGW32__
diff -Nru shadowsocks-libev-3.2.4+ds/debian/patches/backport/0002-Refine-ipv6only-handling.patch shadowsocks-libev-3.2.5+ds/debian/patches/backport/0002-Refine-ipv6only-handling.patch
--- shadowsocks-libev-3.2.4+ds/debian/patches/backport/0002-Refine-ipv6only-handling.patch	1969-12-31 19:00:00.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/debian/patches/backport/0002-Refine-ipv6only-handling.patch	2019-03-20 11:35:36.000000000 -0400
@@ -0,0 +1,147 @@
+From: Max Lv <max.c...@gmail.com>
+Date: Sun, 10 Mar 2019 07:40:07 +0800
+Subject: Refine ipv6only handling
+
+Applied-Upstream: https://github.com/shadowsocks/shadowsocks-libev/commit/3fa9e5724821cd93aa37659f7be8edb475f1f155
+
+---
+ src/local.c    |  8 ++++++--
+ src/netutils.c | 14 +++++++-------
+ src/netutils.h |  2 +-
+ src/redir.c    |  8 ++++++--
+ src/server.c   |  2 +-
+ src/tunnel.c   |  8 ++++++--
+ 6 files changed, 27 insertions(+), 15 deletions(-)
+
+diff --git a/src/local.c b/src/local.c
+index 949053e..d998fd3 100644
+--- a/src/local.c
++++ b/src/local.c
+@@ -1708,7 +1708,7 @@ main(int argc, char **argv)
+             FATAL("failed to find a free port");
+         }
+         snprintf(tmp_port, 8, "%d", port);
+-        if (is_ipv6only(remote_addr, remote_num)) {
++        if (is_ipv6only(remote_addr, remote_num, ipv6first)) {
+             plugin_host = "::1";
+         } else {
+             plugin_host = "127.0.0.1";
+@@ -1748,7 +1748,11 @@ main(int argc, char **argv)
+ #endif
+ 
+     if (local_addr == NULL) {
+-        local_addr = "127.0.0.1";
++        if (is_ipv6only(remote_addr, remote_num, ipv6first)) {
++            local_addr = "::1";
++        } else {
++            local_addr = "127.0.0.1";
++        }
+     }
+ 
+     USE_SYSLOG(argv[0], pid_flags);
+diff --git a/src/netutils.c b/src/netutils.c
+index 6bc14c7..f18fcd9 100644
+--- a/src/netutils.c
++++ b/src/netutils.c
+@@ -285,17 +285,17 @@ validate_hostname(const char *hostname, const int hostname_len)
+ }
+ 
+ int
+-is_ipv6only(ss_addr_t *servers, size_t server_num)
++is_ipv6only(ss_addr_t *servers, size_t server_num, int ipv6first)
+ {
+-    struct cork_ip ip;
+     int i;
+     for (i = 0; i < server_num; i++)
+     {
+-        if (cork_ip_init(&ip, servers[i].host) != -1) {
+-            if (ip.version != 6) {
+-                return 0;
+-            }
+-        } else {
++        struct sockaddr_storage storage;
++        memset(&storage, 0, sizeof(struct sockaddr_storage));
++        if (get_sockaddr(servers[i].host, servers[i].port, &storage, 1, ipv6first) == -1) {
++            FATAL("failed to resolve the provided hostname");
++        }
++        if (storage.ss_family != AF_INET6) {
+             return 0;
+         }
+     }
+diff --git a/src/netutils.h b/src/netutils.h
+index f7f6dc6..70664f1 100644
+--- a/src/netutils.h
++++ b/src/netutils.h
+@@ -108,6 +108,6 @@ int sockaddr_cmp_addr(struct sockaddr_storage *addr1,
+ 
+ int validate_hostname(const char *hostname, const int hostname_len);
+ 
+-int is_ipv6only(ss_addr_t *servers, size_t server_num);
++int is_ipv6only(ss_addr_t *servers, size_t server_num, int ipv6first);
+ 
+ #endif
+diff --git a/src/redir.c b/src/redir.c
+index f5af00b..a21bf4e 100644
+--- a/src/redir.c
++++ b/src/redir.c
+@@ -1067,7 +1067,7 @@ main(int argc, char **argv)
+             FATAL("failed to find a free port");
+         }
+         snprintf(tmp_port, 8, "%d", port);
+-        if (is_ipv6only(remote_addr, remote_num)) {
++        if (is_ipv6only(remote_addr, remote_num, ipv6first)) {
+             plugin_host = "::1";
+         } else {
+             plugin_host = "127.0.0.1";
+@@ -1099,7 +1099,11 @@ main(int argc, char **argv)
+ #endif
+ 
+     if (local_addr == NULL) {
+-        local_addr = "127.0.0.1";
++        if (is_ipv6only(remote_addr, remote_num, ipv6first)) {
++            local_addr = "::1";
++        } else {
++            local_addr = "127.0.0.1";
++        }
+     }
+ 
+     if (fast_open == 1) {
+diff --git a/src/server.c b/src/server.c
+index c00d514..1f0467c 100644
+--- a/src/server.c
++++ b/src/server.c
+@@ -1835,7 +1835,7 @@ main(int argc, char **argv)
+         exit(EXIT_FAILURE);
+     }
+ 
+-    if (is_ipv6only(server_addr, server_num)) {
++    if (is_ipv6only(server_addr, server_num, ipv6first)) {
+         plugin_host = "::1";
+     } else {
+         plugin_host = "127.0.0.1";
+diff --git a/src/tunnel.c b/src/tunnel.c
+index b55b895..ae9244e 100644
+--- a/src/tunnel.c
++++ b/src/tunnel.c
+@@ -1116,7 +1116,7 @@ main(int argc, char **argv)
+             FATAL("failed to find a free port");
+         }
+         snprintf(tmp_port, 8, "%d", port);
+-        if (is_ipv6only(remote_addr, remote_num)) {
++        if (is_ipv6only(remote_addr, remote_num, ipv6first)) {
+             plugin_host = "::1";
+         } else {
+             plugin_host = "127.0.0.1";
+@@ -1156,7 +1156,11 @@ main(int argc, char **argv)
+ #endif
+ 
+     if (local_addr == NULL) {
+-        local_addr = "127.0.0.1";
++        if (is_ipv6only(remote_addr, remote_num, ipv6first)) {
++            local_addr = "::1";
++        } else {
++            local_addr = "127.0.0.1";
++        }
+     }
+ 
+     if (fast_open == 1) {
diff -Nru shadowsocks-libev-3.2.4+ds/debian/patches/series shadowsocks-libev-3.2.5+ds/debian/patches/series
--- shadowsocks-libev-3.2.4+ds/debian/patches/series	2019-03-01 11:31:34.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/debian/patches/series	2019-03-20 11:34:55.000000000 -0400
@@ -1 +1,2 @@
-backport/0001-Refine-ipv6-only-handling.-2300.patch
+backport/0001-Fix-2314.patch
+backport/0002-Refine-ipv6only-handling.patch
diff -Nru shadowsocks-libev-3.2.4+ds/docker/alpine/Dockerfile shadowsocks-libev-3.2.5+ds/docker/alpine/Dockerfile
--- shadowsocks-libev-3.2.4+ds/docker/alpine/Dockerfile	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/docker/alpine/Dockerfile	2019-03-20 11:30:51.000000000 -0400
@@ -6,7 +6,6 @@
 LABEL maintainer="kev <nore...@datageek.info>, Sah <cont...@leesah.name>"
 
 ENV SERVER_ADDR 0.0.0.0
-ENV SERVER_ADDR_IPV6 ::0
 ENV SERVER_PORT 8388
 ENV PASSWORD=
 ENV METHOD      aes-256-gcm
@@ -46,12 +45,10 @@
 
 CMD exec ss-server \
       -s $SERVER_ADDR \
-      -s $SERVER_ADDR_IPV6 \
       -p $SERVER_PORT \
       -k ${PASSWORD:-$(hostname)} \
       -m $METHOD \
       -t $TIMEOUT \
-      --fast-open \
       -d $DNS_ADDRS \
       -u \
       $ARGS
diff -Nru shadowsocks-libev-3.2.4+ds/README.md shadowsocks-libev-3.2.5+ds/README.md
--- shadowsocks-libev-3.2.4+ds/README.md	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/README.md	2019-03-20 11:30:51.000000000 -0400
@@ -9,7 +9,7 @@
 created by [@clowwindy](https://github.com/clowwindy), and maintained by
 [@madeye](https://github.com/madeye) and [@linusyang](https://github.com/linusyang).
 
-Current version: 3.2.4 | [Changelog](debian/changelog)
+Current version: 3.2.5 | [Changelog](debian/changelog)
 
 Travis CI: [![Travis CI](https://travis-ci.org/shadowsocks/shadowsocks-libev.svg?branch=master)](https://travis-ci.org/shadowsocks/shadowsocks-libev)
 
@@ -284,7 +284,7 @@
 wget https://tls.mbed.org/download/mbedtls-$MBEDTLS_VER-gpl.tgz
 tar xvf mbedtls-$MBEDTLS_VER-gpl.tgz
 pushd mbedtls-$MBEDTLS_VER
-make SHARED=1 CFLAGS=-fPIC
+make SHARED=1 CFLAGS="-O2 -fPIC"
 sudo make DESTDIR=/usr install
 popd
 sudo ldconfig
@@ -419,7 +419,7 @@
                                   for local port forwarding.
                                   (only available in tunnel mode)
 
-       [-6]                       Resovle hostname to IPv6 address first.
+       [-6]                       Resolve hostname to IPv6 address first.
 
        [-d <addr>]                Name servers for internal DNS resolver.
                                   (only available in server mode)
@@ -458,7 +458,7 @@
 
 ## Transparent proxy
 
-The latest shadowsocks-libev has provided a *redir* mode. You can configure your Linux-based box or router to proxy all TCP traffic transparently, which is handy if you use a OpenWRT-powered router.
+The latest shadowsocks-libev has provided a *redir* mode. You can configure your Linux-based box or router to proxy all TCP traffic transparently, which is handy if you use an OpenWRT-powered router.
 
     # Create new chain
     iptables -t nat -N SHADOWSOCKS
diff -Nru shadowsocks-libev-3.2.4+ds/src/CMakeLists.txt shadowsocks-libev-3.2.5+ds/src/CMakeLists.txt
--- shadowsocks-libev-3.2.4+ds/src/CMakeLists.txt	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/src/CMakeLists.txt	2019-03-20 11:30:51.000000000 -0400
@@ -86,6 +86,17 @@
         ${SS_PLUGIN_SOURCE}
         )
 
+if (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+find_path(LIBSODIUM_INCLUDE_DIR sodium.h
+        PATHS
+        $ENV{LIBSODIUM_INCLUDE_DIR}
+        $ENV{LIBSODIUM_DIR}/include
+        /usr/local/libsodium/include
+        /opt/libsodium/include
+        /usr/local/include
+)
+include_directories(${LIBSODIUM_INCLUDE_DIR})
+endif ()
 
 if (WITH_STATIC)
 find_library(LIBSODIUM libsodium.a)
@@ -228,6 +239,7 @@
 # Misc
 # Recommend to install shared by default
 install(DIRECTORY ${RUNTIME_SHARED_OUTPUT_DIRECTORY}/
+        USE_SOURCE_PERMISSIONS
         DESTINATION bin)
 
 if (WITH_STATIC)
diff -Nru shadowsocks-libev-3.2.4+ds/src/jconf.c shadowsocks-libev-3.2.5+ds/src/jconf.c
--- shadowsocks-libev-3.2.4+ds/src/jconf.c	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/src/jconf.c	2019-03-20 11:30:51.000000000 -0400
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <time.h>
 
+#include "netutils.h"
 #include "utils.h"
 #include "jconf.h"
 #include "json.h"
@@ -67,9 +68,10 @@
     if (str_in == NULL)
         return;
 
-    int ipv6 = 0, ret = -1, n = 0;
+    int ipv6 = 0, ret = -1, n = 0, len;
     char *pch;
     char *str = strdup(str_in);
+    len = strlen(str_in);
 
     struct cork_ip ip;
     if (cork_ip_init(&ip, str) != -1) {
@@ -84,6 +86,7 @@
         ret = pch - str;
         pch = strchr(pch + 1, ':');
     }
+
     if (n > 1) {
         ipv6 = 1;
         if (str[ret - 1] != ']') {
@@ -104,7 +107,12 @@
         } else {
             addr->host = ss_strndup(str, ret);
         }
-        addr->port = strdup(str + ret + 1);
+        if (ret < len - 1)
+        {
+            addr->port = strdup(str + ret + 1);
+        } else {
+            addr->port = NULL;
+        }
     }
 
     free(str);
diff -Nru shadowsocks-libev-3.2.4+ds/src/jconf.h shadowsocks-libev-3.2.5+ds/src/jconf.h
--- shadowsocks-libev-3.2.4+ds/src/jconf.h	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/src/jconf.h	2019-03-20 11:30:51.000000000 -0400
@@ -44,11 +44,6 @@
 #define UDP_ONLY     3
 
 typedef struct {
-    char *host;
-    char *port;
-} ss_addr_t;
-
-typedef struct {
     char *port;
     char *password;
 } ss_port_password_t;
diff -Nru shadowsocks-libev-3.2.4+ds/src/local.c shadowsocks-libev-3.2.5+ds/src/local.c
--- shadowsocks-libev-3.2.4+ds/src/local.c	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/src/local.c	2019-03-20 11:30:51.000000000 -0400
@@ -1465,12 +1465,13 @@
     char *plugin_port = NULL;
     char tmp_port[8];
 
-    srand(time(NULL));
-
     int remote_num = 0;
     ss_addr_t remote_addr[MAX_REMOTE_NUM];
     char *remote_port = NULL;
 
+    memset(remote_addr, 0, sizeof(ss_addr_t) * MAX_REMOTE_NUM);
+    srand(time(NULL));
+
     static struct option long_options[] = {
         { "reuse-port",  no_argument,       NULL, GETOPT_VAL_REUSE_PORT  },
         { "fast-open",   no_argument,       NULL, GETOPT_VAL_FAST_OPEN   },
@@ -1707,7 +1708,11 @@
             FATAL("failed to find a free port");
         }
         snprintf(tmp_port, 8, "%d", port);
-        plugin_host = "127.0.0.1";
+        if (is_ipv6only(remote_addr, remote_num)) {
+            plugin_host = "::1";
+        } else {
+            plugin_host = "127.0.0.1";
+        }
         plugin_port = tmp_port;
 
 #ifdef __MINGW32__
diff -Nru shadowsocks-libev-3.2.4+ds/src/manager.c shadowsocks-libev-3.2.5+ds/src/manager.c
--- shadowsocks-libev-3.2.4+ds/src/manager.c	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/src/manager.c	2019-03-20 11:30:51.000000000 -0400
@@ -58,8 +58,8 @@
 
 #include "json.h"
 #include "utils.h"
-#include "manager.h"
 #include "netutils.h"
+#include "manager.h"
 
 #ifndef BUF_SIZE
 #define BUF_SIZE 65535
diff -Nru shadowsocks-libev-3.2.4+ds/src/netutils.c shadowsocks-libev-3.2.5+ds/src/netutils.c
--- shadowsocks-libev-3.2.4+ds/src/netutils.c	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/src/netutils.c	2019-03-20 11:30:51.000000000 -0400
@@ -283,3 +283,19 @@
 
     return 1;
 }
+
+int
+is_ipv6only(ss_addr_t *servers, size_t server_num)
+{
+    struct cork_ip ip;
+    int i;
+    for (i = 0; i < server_num; i++)
+    {
+        if (cork_ip_init(&ip, servers[i].host) != -1) {
+            if (ip.version != 6) {
+                return 0;
+            }
+        }
+    }
+    return 1;
+}
diff -Nru shadowsocks-libev-3.2.4+ds/src/netutils.h shadowsocks-libev-3.2.5+ds/src/netutils.h
--- shadowsocks-libev-3.2.4+ds/src/netutils.h	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/src/netutils.h	2019-03-20 11:30:51.000000000 -0400
@@ -52,6 +52,11 @@
 #endif
 #endif
 
+typedef struct {
+    char *host;
+    char *port;
+} ss_addr_t;
+
 /* MPTCP_ENABLED setsockopt values for kernel 4 & 3, best behaviour to be independant of kernel version is to test from newest to the latest values */
 #ifndef MPTCP_ENABLED
 static const char mptcp_enabled_values[] = { 42, 26, 0 };
@@ -103,4 +108,6 @@
 
 int validate_hostname(const char *hostname, const int hostname_len);
 
+int is_ipv6only(ss_addr_t *servers, size_t server_num);
+
 #endif
diff -Nru shadowsocks-libev-3.2.4+ds/src/redir.c shadowsocks-libev-3.2.5+ds/src/redir.c
--- shadowsocks-libev-3.2.4+ds/src/redir.c	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/src/redir.c	2019-03-20 11:30:51.000000000 -0400
@@ -854,13 +854,15 @@
     char *plugin_port = NULL;
     char tmp_port[8];
 
-    int remote_num = 0;
-    ss_addr_t remote_addr[MAX_REMOTE_NUM];
-    char *remote_port = NULL;
-
     int dscp_num    = 0;
     ss_dscp_t *dscp = NULL;
 
+    int remote_num    = 0;
+    char *remote_port = NULL;
+    ss_addr_t remote_addr[MAX_REMOTE_NUM];
+
+    memset(remote_addr, 0, sizeof(ss_addr_t) * MAX_REMOTE_NUM);
+
     static struct option long_options[] = {
         { "fast-open",   no_argument,       NULL, GETOPT_VAL_FAST_OPEN   },
         { "mtu",         required_argument, NULL, GETOPT_VAL_MTU         },
@@ -1065,7 +1067,11 @@
             FATAL("failed to find a free port");
         }
         snprintf(tmp_port, 8, "%d", port);
-        plugin_host = "127.0.0.1";
+        if (is_ipv6only(remote_addr, remote_num)) {
+            plugin_host = "::1";
+        } else {
+            plugin_host = "127.0.0.1";
+        }
         plugin_port = tmp_port;
 
         LOGI("plugin \"%s\" enabled", plugin);
diff -Nru shadowsocks-libev-3.2.4+ds/src/server.c shadowsocks-libev-3.2.5+ds/src/server.c
--- shadowsocks-libev-3.2.4+ds/src/server.c	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/src/server.c	2019-03-20 11:30:51.000000000 -0400
@@ -404,8 +404,8 @@
         }
 
         if (rp->ai_family == AF_INET6) {
-            int ipv6only = host ? 1 : 0;
-            setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, sizeof(ipv6only));
+            int opt = host ? 1 : 0;
+            setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
         }
 
         int opt = 1;
@@ -1607,13 +1607,14 @@
 
     char *server_port = NULL;
     char *plugin_opts = NULL;
+    char *plugin_host = NULL;
     char *plugin_port = NULL;
     char tmp_port[8];
+    char *nameservers = NULL;
 
     int server_num = 0;
     ss_addr_t server_addr[MAX_REMOTE_NUM];
-
-    char *nameservers = NULL;
+    memset(server_addr, 0, sizeof(ss_addr_t) * MAX_REMOTE_NUM);
 
     static struct option long_options[] = {
         { "fast-open",       no_argument,       NULL, GETOPT_VAL_FAST_OPEN   },
@@ -1834,6 +1835,12 @@
         exit(EXIT_FAILURE);
     }
 
+    if (is_ipv6only(server_addr, server_num)) {
+        plugin_host = "::1";
+    } else {
+        plugin_host = "127.0.0.1";
+    }
+
     remote_port = server_port;
 
 #ifdef __MINGW32__
@@ -1991,7 +1998,7 @@
         }
 
         int err = start_plugin(plugin, plugin_opts, server_str,
-                               plugin_port, "127.0.0.1", server_port,
+                               plugin_port, plugin_host, server_port,
 #ifdef __MINGW32__
                                plugin_watcher.port,
 #endif
@@ -2013,7 +2020,7 @@
             const char *port = server_addr[i].port ? server_addr[i].port : server_port;
 
             if (plugin != NULL) {
-                host = "127.0.0.1";
+                host = plugin_host;
             }
 
             if (host && ss_is_ipv6addr(host))
diff -Nru shadowsocks-libev-3.2.4+ds/src/ss-nat shadowsocks-libev-3.2.5+ds/src/ss-nat
--- shadowsocks-libev-3.2.4+ds/src/ss-nat	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/src/ss-nat	2019-03-20 11:30:51.000000000 -0400
@@ -171,29 +171,23 @@
 while getopts ":s:l:S:L:i:I:e:a:b:w:ouUfh" arg; do
 	case "$arg" in
 		s)
-			command -v dig > /dev/null &&
-				server=$(dig +short $OPTARG) ||
-				if ! [[ $OPTARG =~ $IP_REGEX ]]
-				then
-					loger 3 "Hostname detected for server but no dig present to resolve!"
-					exit 1
-				else
-					server=$OPTARG
-				fi
+            if [[ $OPTARG =~ $IP_REGEX ]]
+            then
+                server=$OPTARG
+            else
+                server=$(ping -4 -q -c 1 -s 0 -W 1 -w 1 $OPTARG| head -n 1 | sed -n 's/[^(]*(\([^)]*\)).*/\1/p')
+            fi
 			;;
 		l)
 			local_port=$OPTARG
 			;;
 		S)
-			command -v dig > /dev/null &&
-				SERVER=$(dig +short $OPTARG) ||
-				if ! [[ $OPTARG =~ $IP_REGEX ]]
-				then
-					loger 3 "Hostname detected for UDP server but no dig present to resolve!"
-					exit 1
-				else
-					SERVER=$OPTARG
-				fi
+            if [[ $OPTARG =~ $IP_REGEX ]]
+            then
+                SERVER=$OPTARG
+            else
+                SERVER=$(ping -4 -q -c 1 -s 0 -W 1 -w 1 $OPTARG| head -n 1 | sed -n 's/[^(]*(\([^)]*\)).*/\1/p')
+            fi
 			;;
 		L)
 			LOCAL_PORT=$OPTARG
diff -Nru shadowsocks-libev-3.2.4+ds/src/tunnel.c shadowsocks-libev-3.2.5+ds/src/tunnel.c
--- shadowsocks-libev-3.2.4+ds/src/tunnel.c	2019-03-01 10:45:11.000000000 -0500
+++ shadowsocks-libev-3.2.5+ds/src/tunnel.c	2019-03-20 11:30:51.000000000 -0400
@@ -885,13 +885,15 @@
     char *plugin_port = NULL;
     char tmp_port[8];
 
-    int remote_num = 0;
-    ss_addr_t remote_addr[MAX_REMOTE_NUM];
-    char *remote_port = NULL;
-
     ss_addr_t tunnel_addr = { .host = NULL, .port = NULL };
     char *tunnel_addr_str = NULL;
 
+    int remote_num    = 0;
+    char *remote_port = NULL;
+    ss_addr_t remote_addr[MAX_REMOTE_NUM];
+
+    memset(remote_addr, 0, sizeof(ss_addr_t) * MAX_REMOTE_NUM);
+
     static struct option long_options[] = {
         { "fast-open",   no_argument,       NULL, GETOPT_VAL_FAST_OPEN   },
         { "mtu",         required_argument, NULL, GETOPT_VAL_MTU         },
@@ -1114,7 +1116,11 @@
             FATAL("failed to find a free port");
         }
         snprintf(tmp_port, 8, "%d", port);
-        plugin_host = "127.0.0.1";
+        if (is_ipv6only(remote_addr, remote_num)) {
+            plugin_host = "::1";
+        } else {
+            plugin_host = "127.0.0.1";
+        }
         plugin_port = tmp_port;
 
 #ifdef __MINGW32__

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to