From 6a0f853d15400901f9b54f66af3b3ae74f322b92 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Tue, 29 Oct 2013 17:05:59 +0800 Subject: [PATCH 1/6] add multi-config support --- src/jconf.c | 26 ++++++++++++++++++++++++-- src/jconf.h | 8 +++++++- src/local.c | 21 +++++++++++++-------- src/local.h | 3 +-- src/redir.c | 21 +++++++++++++-------- src/redir.h | 3 +-- src/server.c | 2 +- 7 files changed, 60 insertions(+), 24 deletions(-) diff --git a/src/jconf.c b/src/jconf.c index dbf27ce0..f1a14d9a 100644 --- a/src/jconf.c +++ b/src/jconf.c @@ -52,6 +52,27 @@ static int to_int(const json_value *value) return 0; } +static void parse_addr(const char *str, remote_addr_t *addr) { + int ret = -1; + char *pch; + pch = strchr(str, ':'); + while (pch != NULL) + { + ret = pch - str; + pch = strchr(pch + 1, ':'); + } + if (ret == -1) + { + addr->host = str; + addr->port = NULL; + } + else + { + addr->host = ss_strndup(str, ret); + addr->port = str + ret + 1; + } +} + jconf_t *read_jconf(const char* file) { @@ -101,13 +122,14 @@ jconf_t *read_jconf(const char* file) { if (j >= MAX_REMOTE_NUM) break; json_value *v = value->u.array.values[j]; - conf.remote_host[j] = to_string(v); + parse_addr(to_string(v), conf.remote_addr + j); conf.remote_num = j + 1; } } else if (value->type == json_string) { - conf.remote_host[0] = to_string(value); + conf.remote_addr[0].host = to_string(value); + conf.remote_addr[0].port = NULL; conf.remote_num = 1; } } diff --git a/src/jconf.h b/src/jconf.h index a47fc776..ca99142e 100644 --- a/src/jconf.h +++ b/src/jconf.h @@ -6,10 +6,16 @@ #define DNS_THREAD_NUM 4 #define MAX_UDP_CONN_NUM 4096 +typedef struct +{ + char *host; + char *port; +} remote_addr_t; + typedef struct { int remote_num; - char *remote_host[MAX_REMOTE_NUM]; + remote_addr_t remote_addr[MAX_REMOTE_NUM]; char *remote_port; char *local_port; char *password; diff --git a/src/local.c b/src/local.c index 867cc17d..819c5f40 100644 --- a/src/local.c +++ b/src/local.c @@ -751,7 +751,11 @@ static void accept_cb (EV_P_ ev_io *w, int revents) hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; int index = rand() % listener->remote_num; - int err = getaddrinfo(listener->remote_host[index], listener->remote_port, &hints, &res); + if (verbose) + { + LOGD("connect to %s:%s", listener->remote_addr[index].host, listener->remote_addr[index].port); + } + int err = getaddrinfo(listener->remote_addr[index].host, listener->remote_addr[index].port, &hints, &res); if (err) { ERROR("getaddrinfo"); @@ -804,7 +808,7 @@ int main (int argc, char **argv) char *iface = NULL; int remote_num = 0; - char *remote_host[MAX_REMOTE_NUM]; + remote_addr_t remote_addr[MAX_REMOTE_NUM]; char *remote_port = NULL; opterr = 0; @@ -814,7 +818,8 @@ int main (int argc, char **argv) switch (c) { case 's': - remote_host[remote_num++] = optarg; + remote_addr[remote_num].host = optarg; + remote_addr[remote_num++].port = NULL; break; case 'p': remote_port = optarg; @@ -867,7 +872,7 @@ int main (int argc, char **argv) remote_num = conf->remote_num; for (i = 0; i < remote_num; i++) { - remote_host[i] = conf->remote_host[i]; + remote_addr[i] = conf->remote_addr[i]; } } if (remote_port == NULL) remote_port = conf->remote_port; @@ -922,13 +927,13 @@ int main (int argc, char **argv) // Setup proxy context struct listen_ctx listen_ctx; listen_ctx.remote_num = remote_num; - listen_ctx.remote_host = malloc(sizeof(char *) * remote_num); + listen_ctx.remote_addr = malloc(sizeof(remote_addr_t) * remote_num); while (remote_num > 0) { int index = --remote_num; - listen_ctx.remote_host[index] = remote_host[index]; + if (remote_addr[index].port == NULL) remote_addr[index].port = remote_port; + listen_ctx.remote_addr[index] = remote_addr[index]; } - listen_ctx.remote_port = remote_port; listen_ctx.timeout = atoi(timeout); listen_ctx.fd = listenfd; listen_ctx.iface = iface; @@ -946,7 +951,7 @@ int main (int argc, char **argv) if (udprelay) { LOGD("udprelay enabled."); - udprelay_init(local_addr, local_port, remote_host[0], remote_port, m, iface); + udprelay_init(local_addr, local_port, remote_addr[0].host, remote_addr[0].port, m, iface); } ev_run (loop, 0); diff --git a/src/local.h b/src/local.h index ac716d2a..e4766d57 100644 --- a/src/local.h +++ b/src/local.h @@ -8,8 +8,7 @@ struct listen_ctx { ev_io io; - char **remote_host; - char *remote_port; + remote_addr_t *remote_addr; char *iface; int remote_num; int method; diff --git a/src/redir.c b/src/redir.c index ff254949..ef6c4f66 100644 --- a/src/redir.c +++ b/src/redir.c @@ -619,7 +619,11 @@ static void accept_cb (EV_P_ ev_io *w, int revents) hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; int index = rand() % listener->remote_num; - err = getaddrinfo(listener->remote_host[index], listener->remote_port, &hints, &res); + if (verbose) + { + LOGD("connect to %s:%s", listener->remote_addr[index].host, listener->remote_addr[index].port); + } + err = getaddrinfo(listener->remote_addr[index].host, listener->remote_addr[index].port, &hints, &res); if (err) { ERROR("getaddrinfo"); @@ -670,7 +674,7 @@ int main (int argc, char **argv) char *conf_path = NULL; int remote_num = 0; - char *remote_host[MAX_REMOTE_NUM]; + remote_addr_t remote_addr[MAX_REMOTE_NUM]; char *remote_port = NULL; opterr = 0; @@ -680,7 +684,8 @@ int main (int argc, char **argv) switch (c) { case 's': - remote_host[remote_num++] = optarg; + remote_addr[remote_num].host = optarg; + remote_addr[remote_num++].port = NULL; break; case 'p': remote_port = optarg; @@ -724,7 +729,7 @@ int main (int argc, char **argv) remote_num = conf->remote_num; for (i = 0; i < remote_num; i++) { - remote_host[i] = conf->remote_host[i]; + remote_addr[i] = conf->remote_addr[i]; } } if (remote_port == NULL) remote_port = conf->remote_port; @@ -755,7 +760,7 @@ int main (int argc, char **argv) signal(SIGABRT, SIG_IGN); // Setup keys - LOGD("calculating ciphers..."); + LOGD("initialize ciphers... %s", method); int m = enc_init(password, method); // Setup socket @@ -775,13 +780,13 @@ int main (int argc, char **argv) // Setup proxy context struct listen_ctx listen_ctx; listen_ctx.remote_num = remote_num; - listen_ctx.remote_host = malloc(sizeof(char *) * remote_num); + listen_ctx.remote_addr = malloc(sizeof(remote_addr_t) * remote_num); while (remote_num > 0) { int index = --remote_num; - listen_ctx.remote_host[index] = remote_host[index]; + if (remote_addr[index].port == NULL) remote_addr[index].port = remote_port; + listen_ctx.remote_addr[index] = remote_addr[index]; } - listen_ctx.remote_port = remote_port; listen_ctx.timeout = atoi(timeout); listen_ctx.fd = listenfd; listen_ctx.method = m; diff --git a/src/redir.h b/src/redir.h index c5300133..2213be6f 100644 --- a/src/redir.h +++ b/src/redir.h @@ -8,8 +8,7 @@ struct listen_ctx { ev_io io; - char **remote_host; - char *remote_port; + remote_addr_t *remote_host; int remote_num; int timeout; int fd; diff --git a/src/server.c b/src/server.c index b7de0f90..3b9547e7 100644 --- a/src/server.c +++ b/src/server.c @@ -969,7 +969,7 @@ int main (int argc, char **argv) server_num = conf->remote_num; for (i = 0; i < server_num; i++) { - server_host[i] = conf->remote_host[i]; + server_host[i] = conf->remote_addr[i].host; } } if (server_port == NULL) server_port = conf->remote_port; From 183f02162820b217e384aa5e2f73b37c5d80c774 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Tue, 29 Oct 2013 02:09:03 -0700 Subject: [PATCH 2/6] fix build error --- src/redir.c | 4 ---- src/redir.h | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/redir.c b/src/redir.c index ef6c4f66..ba5ce8ec 100644 --- a/src/redir.c +++ b/src/redir.c @@ -619,10 +619,6 @@ static void accept_cb (EV_P_ ev_io *w, int revents) hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; int index = rand() % listener->remote_num; - if (verbose) - { - LOGD("connect to %s:%s", listener->remote_addr[index].host, listener->remote_addr[index].port); - } err = getaddrinfo(listener->remote_addr[index].host, listener->remote_addr[index].port, &hints, &res); if (err) { diff --git a/src/redir.h b/src/redir.h index 2213be6f..da765ee8 100644 --- a/src/redir.h +++ b/src/redir.h @@ -8,7 +8,7 @@ struct listen_ctx { ev_io io; - remote_addr_t *remote_host; + remote_addr_t *remote_addr; int remote_num; int timeout; int fd; From 4606acd773782cecb5f910bbf103459ed3d445bf Mon Sep 17 00:00:00 2001 From: Max Lv Date: Tue, 29 Oct 2013 17:05:59 +0800 Subject: [PATCH 3/6] add multi-config support --- src/jconf.c | 26 ++++++++++++++++++++++++-- src/jconf.h | 8 +++++++- src/local.c | 21 +++++++++++++-------- src/local.h | 3 +-- src/redir.c | 21 +++++++++++++-------- src/redir.h | 3 +-- src/server.c | 2 +- 7 files changed, 60 insertions(+), 24 deletions(-) diff --git a/src/jconf.c b/src/jconf.c index dbf27ce0..f1a14d9a 100644 --- a/src/jconf.c +++ b/src/jconf.c @@ -52,6 +52,27 @@ static int to_int(const json_value *value) return 0; } +static void parse_addr(const char *str, remote_addr_t *addr) { + int ret = -1; + char *pch; + pch = strchr(str, ':'); + while (pch != NULL) + { + ret = pch - str; + pch = strchr(pch + 1, ':'); + } + if (ret == -1) + { + addr->host = str; + addr->port = NULL; + } + else + { + addr->host = ss_strndup(str, ret); + addr->port = str + ret + 1; + } +} + jconf_t *read_jconf(const char* file) { @@ -101,13 +122,14 @@ jconf_t *read_jconf(const char* file) { if (j >= MAX_REMOTE_NUM) break; json_value *v = value->u.array.values[j]; - conf.remote_host[j] = to_string(v); + parse_addr(to_string(v), conf.remote_addr + j); conf.remote_num = j + 1; } } else if (value->type == json_string) { - conf.remote_host[0] = to_string(value); + conf.remote_addr[0].host = to_string(value); + conf.remote_addr[0].port = NULL; conf.remote_num = 1; } } diff --git a/src/jconf.h b/src/jconf.h index a47fc776..ca99142e 100644 --- a/src/jconf.h +++ b/src/jconf.h @@ -6,10 +6,16 @@ #define DNS_THREAD_NUM 4 #define MAX_UDP_CONN_NUM 4096 +typedef struct +{ + char *host; + char *port; +} remote_addr_t; + typedef struct { int remote_num; - char *remote_host[MAX_REMOTE_NUM]; + remote_addr_t remote_addr[MAX_REMOTE_NUM]; char *remote_port; char *local_port; char *password; diff --git a/src/local.c b/src/local.c index 5a69aa13..052a5ffb 100644 --- a/src/local.c +++ b/src/local.c @@ -751,7 +751,11 @@ static void accept_cb (EV_P_ ev_io *w, int revents) hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; int index = rand() % listener->remote_num; - int err = getaddrinfo(listener->remote_host[index], listener->remote_port, &hints, &res); + if (verbose) + { + LOGD("connect to %s:%s", listener->remote_addr[index].host, listener->remote_addr[index].port); + } + int err = getaddrinfo(listener->remote_addr[index].host, listener->remote_addr[index].port, &hints, &res); if (err) { ERROR("getaddrinfo"); @@ -804,7 +808,7 @@ int main (int argc, char **argv) char *iface = NULL; int remote_num = 0; - char *remote_host[MAX_REMOTE_NUM]; + remote_addr_t remote_addr[MAX_REMOTE_NUM]; char *remote_port = NULL; opterr = 0; @@ -814,7 +818,8 @@ int main (int argc, char **argv) switch (c) { case 's': - remote_host[remote_num++] = optarg; + remote_addr[remote_num].host = optarg; + remote_addr[remote_num++].port = NULL; break; case 'p': remote_port = optarg; @@ -867,7 +872,7 @@ int main (int argc, char **argv) remote_num = conf->remote_num; for (i = 0; i < remote_num; i++) { - remote_host[i] = conf->remote_host[i]; + remote_addr[i] = conf->remote_addr[i]; } } if (remote_port == NULL) remote_port = conf->remote_port; @@ -922,13 +927,13 @@ int main (int argc, char **argv) // Setup proxy context struct listen_ctx listen_ctx; listen_ctx.remote_num = remote_num; - listen_ctx.remote_host = malloc(sizeof(char *) * remote_num); + listen_ctx.remote_addr = malloc(sizeof(remote_addr_t) * remote_num); while (remote_num > 0) { int index = --remote_num; - listen_ctx.remote_host[index] = remote_host[index]; + if (remote_addr[index].port == NULL) remote_addr[index].port = remote_port; + listen_ctx.remote_addr[index] = remote_addr[index]; } - listen_ctx.remote_port = remote_port; listen_ctx.timeout = atoi(timeout); listen_ctx.fd = listenfd; listen_ctx.iface = iface; @@ -946,7 +951,7 @@ int main (int argc, char **argv) if (udprelay) { LOGD("udprelay enabled."); - udprelay_init(local_addr, local_port, remote_host[0], remote_port, m, iface); + udprelay_init(local_addr, local_port, remote_addr[0].host, remote_addr[0].port, m, iface); } ev_run (loop, 0); diff --git a/src/local.h b/src/local.h index ac716d2a..e4766d57 100644 --- a/src/local.h +++ b/src/local.h @@ -8,8 +8,7 @@ struct listen_ctx { ev_io io; - char **remote_host; - char *remote_port; + remote_addr_t *remote_addr; char *iface; int remote_num; int method; diff --git a/src/redir.c b/src/redir.c index 99e56af2..9cf137bf 100644 --- a/src/redir.c +++ b/src/redir.c @@ -619,7 +619,11 @@ static void accept_cb (EV_P_ ev_io *w, int revents) hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; int index = rand() % listener->remote_num; - err = getaddrinfo(listener->remote_host[index], listener->remote_port, &hints, &res); + if (verbose) + { + LOGD("connect to %s:%s", listener->remote_addr[index].host, listener->remote_addr[index].port); + } + err = getaddrinfo(listener->remote_addr[index].host, listener->remote_addr[index].port, &hints, &res); if (err) { ERROR("getaddrinfo"); @@ -670,7 +674,7 @@ int main (int argc, char **argv) char *conf_path = NULL; int remote_num = 0; - char *remote_host[MAX_REMOTE_NUM]; + remote_addr_t remote_addr[MAX_REMOTE_NUM]; char *remote_port = NULL; opterr = 0; @@ -680,7 +684,8 @@ int main (int argc, char **argv) switch (c) { case 's': - remote_host[remote_num++] = optarg; + remote_addr[remote_num].host = optarg; + remote_addr[remote_num++].port = NULL; break; case 'p': remote_port = optarg; @@ -724,7 +729,7 @@ int main (int argc, char **argv) remote_num = conf->remote_num; for (i = 0; i < remote_num; i++) { - remote_host[i] = conf->remote_host[i]; + remote_addr[i] = conf->remote_addr[i]; } } if (remote_port == NULL) remote_port = conf->remote_port; @@ -755,7 +760,7 @@ int main (int argc, char **argv) signal(SIGABRT, SIG_IGN); // Setup keys - LOGD("calculating ciphers..."); + LOGD("initialize ciphers... %s", method); int m = enc_init(password, method); // Setup socket @@ -775,13 +780,13 @@ int main (int argc, char **argv) // Setup proxy context struct listen_ctx listen_ctx; listen_ctx.remote_num = remote_num; - listen_ctx.remote_host = malloc(sizeof(char *) * remote_num); + listen_ctx.remote_addr = malloc(sizeof(remote_addr_t) * remote_num); while (remote_num > 0) { int index = --remote_num; - listen_ctx.remote_host[index] = remote_host[index]; + if (remote_addr[index].port == NULL) remote_addr[index].port = remote_port; + listen_ctx.remote_addr[index] = remote_addr[index]; } - listen_ctx.remote_port = remote_port; listen_ctx.timeout = atoi(timeout); listen_ctx.fd = listenfd; listen_ctx.method = m; diff --git a/src/redir.h b/src/redir.h index c5300133..2213be6f 100644 --- a/src/redir.h +++ b/src/redir.h @@ -8,8 +8,7 @@ struct listen_ctx { ev_io io; - char **remote_host; - char *remote_port; + remote_addr_t *remote_host; int remote_num; int timeout; int fd; diff --git a/src/server.c b/src/server.c index befac8e1..4a8f32a6 100644 --- a/src/server.c +++ b/src/server.c @@ -969,7 +969,7 @@ int main (int argc, char **argv) server_num = conf->remote_num; for (i = 0; i < server_num; i++) { - server_host[i] = conf->remote_host[i]; + server_host[i] = conf->remote_addr[i].host; } } if (server_port == NULL) server_port = conf->remote_port; From 26c57d61ef0191287a2c2570029c862aecac2899 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Tue, 29 Oct 2013 02:09:03 -0700 Subject: [PATCH 4/6] fix build error --- src/redir.c | 4 ---- src/redir.h | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/redir.c b/src/redir.c index 9cf137bf..abeda551 100644 --- a/src/redir.c +++ b/src/redir.c @@ -619,10 +619,6 @@ static void accept_cb (EV_P_ ev_io *w, int revents) hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; int index = rand() % listener->remote_num; - if (verbose) - { - LOGD("connect to %s:%s", listener->remote_addr[index].host, listener->remote_addr[index].port); - } err = getaddrinfo(listener->remote_addr[index].host, listener->remote_addr[index].port, &hints, &res); if (err) { diff --git a/src/redir.h b/src/redir.h index 2213be6f..da765ee8 100644 --- a/src/redir.h +++ b/src/redir.h @@ -8,7 +8,7 @@ struct listen_ctx { ev_io io; - remote_addr_t *remote_host; + remote_addr_t *remote_addr; int remote_num; int timeout; int fd; From 99ebddcd95b51b6801f05e619566d54731e52e56 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Tue, 12 Nov 2013 03:59:56 +0000 Subject: [PATCH 5/6] bump version --- configure | 20 ++++++++++---------- configure.ac | 2 +- debian/changelog | 7 +++++++ 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/configure b/configure index e048b227..833a1b13 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for shadowsocks 1.4.0. +# Generated by GNU Autoconf 2.68 for shadowsocks 1.4.1. # # Report bugs to . # @@ -570,8 +570,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='shadowsocks' PACKAGE_TARNAME='shadowsocks' -PACKAGE_VERSION='1.4.0' -PACKAGE_STRING='shadowsocks 1.4.0' +PACKAGE_VERSION='1.4.1' +PACKAGE_STRING='shadowsocks 1.4.1' PACKAGE_BUGREPORT='max.c.lv@gmail.com' PACKAGE_URL='' @@ -1306,7 +1306,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures shadowsocks 1.4.0 to adapt to many kinds of systems. +\`configure' configures shadowsocks 1.4.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1376,7 +1376,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of shadowsocks 1.4.0:";; + short | recursive ) echo "Configuration of shadowsocks 1.4.1:";; esac cat <<\_ACEOF @@ -1492,7 +1492,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -shadowsocks configure 1.4.0 +shadowsocks configure 1.4.1 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2014,7 +2014,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by shadowsocks $as_me 1.4.0, which was +It was created by shadowsocks $as_me 1.4.1, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2834,7 +2834,7 @@ fi # Define the identity of the package. PACKAGE='shadowsocks' - VERSION='1.4.0' + VERSION='1.4.1' cat >>confdefs.h <<_ACEOF @@ -15457,7 +15457,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by shadowsocks $as_me 1.4.0, which was +This file was extended by shadowsocks $as_me 1.4.1, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15523,7 +15523,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -shadowsocks config.status 1.4.0 +shadowsocks config.status 1.4.1 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index e301f65e..4f971f68 100755 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. AC_PREREQ([2.67]) -AC_INIT([shadowsocks], [1.4.0], [max.c.lv@gmail.com]) +AC_INIT([shadowsocks], [1.4.1], [max.c.lv@gmail.com]) AC_CONFIG_SRCDIR([src/encrypt.c]) AC_CONFIG_HEADERS([config.h]) diff --git a/debian/changelog b/debian/changelog index dba792ba..f7dc1105 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +shadowsocks (1.4.1-1) unstable; urgency=low + + * Add multi-port support. + * Add PolarSSL support by @linusyang + + -- Max Lv Tue, 12 Nov 2013 03:57:21 +0000 + shadowsocks (1.4.0-1) unstable; urgency=low * Add standard socks5 udp support. From 41ca47ecd263e6499e39aeea3025ffe79a3ef55e Mon Sep 17 00:00:00 2001 From: Max Lv Date: Tue, 12 Nov 2013 04:02:07 +0000 Subject: [PATCH 6/6] update readme --- README.md | 5 +++++ debian/changelog | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f556ec98..9b58b952 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,11 @@ Current version: 1.4.0 | [![Build Status](https://travis-ci.org/madeye/shadowsoc Changelog --------- +1.4.1 -- Tue, 12 Nov 2013 03:57:21 +0000 + + * Add multi-port support. + * Add PolarSSL support by @linusyang. + 1.4.0 -- Sun, 08 Sep 2013 02:20:40 +0000 * Add standard socks5 udp support. diff --git a/debian/changelog b/debian/changelog index f7dc1105..e1bd3ac4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,7 +1,7 @@ shadowsocks (1.4.1-1) unstable; urgency=low * Add multi-port support. - * Add PolarSSL support by @linusyang + * Add PolarSSL support by @linusyang. -- Max Lv Tue, 12 Nov 2013 03:57:21 +0000