Browse Source

Add HTTP/SNI parser (#809)

* WiP: add HTTP/SNI parser

* WiP: replace hostname with HTTP/SNI header

* WiP: add ACL

* Fix white list

* Replace free() with ss_free()

* Refine sockaddr handling

* Add HTTP/SNI support to redir
pull/814/head
Max Lv 8 years ago
committed by GitHub
parent
commit
64870a276b
33 changed files with 4146 additions and 255 deletions
  1. 21
      Makefile.in
  2. 1283
      aclocal.m4
  3. 0
      auto/config.rpath
  4. 3
      config.h.in
  5. 1572
      configure
  6. 12
      configure.ac
  7. 9
      doc/Makefile.in
  8. 18
      libcork/Makefile.am
  9. 27
      libcork/Makefile.in
  10. 9
      libev/Makefile.in
  11. 18
      libipset/Makefile.am
  12. 27
      libipset/Makefile.in
  13. 19
      libudns/Makefile.am
  14. 27
      libudns/Makefile.in
  15. 16
      src/Makefile.am
  16. 224
      src/Makefile.in
  17. 121
      src/acl.c
  18. 8
      src/acl.h
  19. 140
      src/http.c
  20. 34
      src/http.h
  21. 2
      src/jconf.c
  22. 222
      src/local.c
  23. 4
      src/local.h
  24. 26
      src/manager.c
  25. 34
      src/protocol.h
  26. 58
      src/redir.c
  27. 3
      src/redir.h
  28. 122
      src/rule.c
  29. 53
      src/rule.h
  30. 12
      src/server.c
  31. 1
      src/shadowsocks.h
  32. 243
      src/tls.c
  33. 33
      src/tls.h

21
Makefile.in

@ -84,11 +84,13 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
$(srcdir)/config.h.in $(srcdir)/shadowsocks-libev.pc.in \
AUTHORS COPYING INSTALL auto/ar-lib auto/compile \
auto/config.guess auto/config.sub auto/depcomp auto/install-sh \
auto/missing auto/ltmain.sh $(top_srcdir)/auto/ar-lib \
$(top_srcdir)/auto/compile $(top_srcdir)/auto/config.guess \
$(top_srcdir)/auto/config.sub $(top_srcdir)/auto/install-sh \
$(top_srcdir)/auto/ltmain.sh $(top_srcdir)/auto/missing
auto/config.guess auto/config.rpath auto/config.sub \
auto/depcomp auto/install-sh auto/missing auto/ltmain.sh \
$(top_srcdir)/auto/ar-lib $(top_srcdir)/auto/compile \
$(top_srcdir)/auto/config.guess \
$(top_srcdir)/auto/config.rpath $(top_srcdir)/auto/config.sub \
$(top_srcdir)/auto/install-sh $(top_srcdir)/auto/ltmain.sh \
$(top_srcdir)/auto/missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
$(top_srcdir)/m4/ax_tls.m4 $(top_srcdir)/m4/inet_ntop.m4 \
@ -262,6 +264,7 @@ EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GZIP = @GZIP@
HAVE_LIBPCRE = @HAVE_LIBPCRE@
INET_NTOP_LIB = @INET_NTOP_LIB@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@ -271,11 +274,16 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBPCRE = @LIBPCRE@
LIBPCRE_CFLAGS = @LIBPCRE_CFLAGS@
LIBPCRE_LIBS = @LIBPCRE_LIBS@
LIBPCRE_PREFIX = @LIBPCRE_PREFIX@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LTLIBPCRE = @LTLIBPCRE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
@ -295,6 +303,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@

1283
aclocal.m4
File diff suppressed because it is too large
View File

0
auto/config.rpath

3
config.h.in

@ -79,6 +79,9 @@
/* Define to 1 if you have the <langinfo.h> header file. */
#undef HAVE_LANGINFO_H
/* Define if you have the libpcre library. */
#undef HAVE_LIBPCRE
/* Define to 1 if you have the `rt' library (-lrt). */
#undef HAVE_LIBRT

1572
configure
File diff suppressed because it is too large
View File

12
configure.ac

@ -20,6 +20,18 @@ AC_DISABLE_STATIC
AC_DISABLE_SHARED
LT_INIT([dlopen])
dnl Checks for libpcre
PKG_CHECK_MODULES([LIBPCRE], [libpcre], HAVE_LIBPCRE=yes; AC_DEFINE(HAVE_LIBPCRE, 1),
[AC_LIB_HAVE_LINKFLAGS(pcre,, [#include <pcre.h>], [pcre_exec(0,0,0,0,0,0,0,0);])
if test x$ac_cv_libpcre = xyes; then
AC_SUBST([LIBPCRE_LIBS], [$LIBPCRE])
else
AC_MSG_ERROR([[***
*** libpcre was not found.
***]])
fi
])
dnl Checks for using shared libraries from system
AC_ARG_ENABLE(
[system-shared-lib],

9
doc/Makefile.in

@ -178,6 +178,7 @@ EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GZIP = @GZIP@
HAVE_LIBPCRE = @HAVE_LIBPCRE@
INET_NTOP_LIB = @INET_NTOP_LIB@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@ -187,11 +188,16 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBPCRE = @LIBPCRE@
LIBPCRE_CFLAGS = @LIBPCRE_CFLAGS@
LIBPCRE_LIBS = @LIBPCRE_LIBS@
LIBPCRE_PREFIX = @LIBPCRE_PREFIX@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LTLIBPCRE = @LTLIBPCRE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
@ -211,6 +217,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@

18
libcork/Makefile.am

@ -1,21 +1,3 @@
# This file is part of libasyncns.
#
# Copyright 2005-2008 Lennart Poettering
#
# libasyncns is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 2.1 of the
# License, or (at your option) any later version.
#
# libasyncns is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with libasyncns. If not, see
# <http://www.gnu.org/licenses/>.
noinst_LTLIBRARIES = libcork.la
cli_src = cli/commands.c

27
libcork/Makefile.in

@ -14,24 +14,6 @@
@SET_MAKE@
# This file is part of libasyncns.
#
# Copyright 2005-2008 Lennart Poettering
#
# libasyncns is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 2.1 of the
# License, or (at your option) any later version.
#
# libasyncns is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with libasyncns. If not, see
# <http://www.gnu.org/licenses/>.
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
@ -231,6 +213,7 @@ EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GZIP = @GZIP@
HAVE_LIBPCRE = @HAVE_LIBPCRE@
INET_NTOP_LIB = @INET_NTOP_LIB@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@ -240,11 +223,16 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBPCRE = @LIBPCRE@
LIBPCRE_CFLAGS = @LIBPCRE_CFLAGS@
LIBPCRE_LIBS = @LIBPCRE_LIBS@
LIBPCRE_PREFIX = @LIBPCRE_PREFIX@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LTLIBPCRE = @LTLIBPCRE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
@ -264,6 +252,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@

9
libev/Makefile.in

@ -198,6 +198,7 @@ EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GZIP = @GZIP@
HAVE_LIBPCRE = @HAVE_LIBPCRE@
INET_NTOP_LIB = @INET_NTOP_LIB@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@ -207,11 +208,16 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBPCRE = @LIBPCRE@
LIBPCRE_CFLAGS = @LIBPCRE_CFLAGS@
LIBPCRE_LIBS = @LIBPCRE_LIBS@
LIBPCRE_PREFIX = @LIBPCRE_PREFIX@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LTLIBPCRE = @LTLIBPCRE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
@ -231,6 +237,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@

18
libipset/Makefile.am

@ -1,21 +1,3 @@
# This file is part of libasyncns.
#
# Copyright 2005-2008 Lennart Poettering
#
# libasyncns is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 2.1 of the
# License, or (at your option) any later version.
#
# libasyncns is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with libasyncns. If not, see
# <http://www.gnu.org/licenses/>.
noinst_LTLIBRARIES = libipset.la
bdd_src = bdd/assignments.c bdd/basics.c bdd/bdd-iterator.c bdd/expanded.c \

27
libipset/Makefile.in

@ -14,24 +14,6 @@
@SET_MAKE@
# This file is part of libasyncns.
#
# Copyright 2005-2008 Lennart Poettering
#
# libasyncns is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 2.1 of the
# License, or (at your option) any later version.
#
# libasyncns is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with libasyncns. If not, see
# <http://www.gnu.org/licenses/>.
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
@ -227,6 +209,7 @@ EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GZIP = @GZIP@
HAVE_LIBPCRE = @HAVE_LIBPCRE@
INET_NTOP_LIB = @INET_NTOP_LIB@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@ -236,11 +219,16 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBPCRE = @LIBPCRE@
LIBPCRE_CFLAGS = @LIBPCRE_CFLAGS@
LIBPCRE_LIBS = @LIBPCRE_LIBS@
LIBPCRE_PREFIX = @LIBPCRE_PREFIX@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LTLIBPCRE = @LTLIBPCRE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
@ -260,6 +248,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@

19
libudns/Makefile.am

@ -1,25 +1,8 @@
# This file is part of libasyncns.
#
# Copyright 2005-2008 Lennart Poettering
#
# libasyncns is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 2.1 of the
# License, or (at your option) any later version.
#
# libasyncns is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with libasyncns. If not, see
# <http://www.gnu.org/licenses/>.
SRCS = udns_dn.c udns_dntosp.c udns_parse.c udns_resolver.c udns_init.c \
udns_misc.c udns_XtoX.c \
udns_rr_a.c udns_rr_ptr.c udns_rr_mx.c udns_rr_txt.c udns_bl.c \
udns_rr_srv.c udns_rr_naptr.c udns_codes.c udns_jran.c
noinst_LTLIBRARIES=libudns.la
libudns_la_SOURCES= ${SRCS}
libudns_la_LDFLAGS= -static

27
libudns/Makefile.in

@ -14,24 +14,6 @@
@SET_MAKE@
# This file is part of libasyncns.
#
# Copyright 2005-2008 Lennart Poettering
#
# libasyncns is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 2.1 of the
# License, or (at your option) any later version.
#
# libasyncns is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with libasyncns. If not, see
# <http://www.gnu.org/licenses/>.
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
@ -219,6 +201,7 @@ EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GZIP = @GZIP@
HAVE_LIBPCRE = @HAVE_LIBPCRE@
INET_NTOP_LIB = @INET_NTOP_LIB@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@ -228,11 +211,16 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBPCRE = @LIBPCRE@
LIBPCRE_CFLAGS = @LIBPCRE_CFLAGS@
LIBPCRE_LIBS = @LIBPCRE_LIBS@
LIBPCRE_PREFIX = @LIBPCRE_PREFIX@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LTLIBPCRE = @LTLIBPCRE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
@ -252,6 +240,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@

16
src/Makefile.am

@ -9,10 +9,11 @@ AM_CFLAGS += -I$(top_srcdir)/libsodium/src/libsodium/include
endif
AM_CFLAGS += -I$(top_srcdir)/libipset/include
AM_CFLAGS += -I$(top_srcdir)/libcork/include
AM_CFLAGS += $(LIBPCRE_CFLAGS)
SS_COMMON_LIBS = $(top_builddir)/libipset/libipset.la \
$(top_builddir)/libcork/libcork.la \
$(INET_NTOP_LIB)
$(INET_NTOP_LIB) $(LIBPCRE_LIBS)
if USE_SYSTEM_SHARED_LIB
SS_COMMON_LIBS += -lev -lsodium -lm
else
@ -25,6 +26,10 @@ if !BUILD_WINCOMPAT
bin_PROGRAMS += ss-server ss-manager
endif
sni_src = http.c \
tls.c \
rule.c
ss_local_SOURCES = utils.c \
jconf.c \
json.c \
@ -33,7 +38,8 @@ ss_local_SOURCES = utils.c \
cache.c \
acl.c \
netutils.c \
local.c
local.c \
$(sni_src)
ss_tunnel_SOURCES = utils.c \
jconf.c \
@ -53,7 +59,8 @@ ss_server_SOURCES = utils.c \
cache.c \
acl.c \
resolv.c \
server.c
server.c \
$(sni_src)
ss_manager_SOURCES = utils.c \
jconf.c \
@ -94,7 +101,8 @@ ss_redir_SOURCES = utils.c \
netutils.c \
cache.c \
udprelay.c \
redir.c
redir.c \
$(sni_src)
ss_redir_CFLAGS = $(AM_CFLAGS) -DMODULE_REDIR
ss_redir_LDADD = $(SS_COMMON_LIBS)
if USE_SYSTEM_SHARED_LIB

224
src/Makefile.in

@ -153,15 +153,18 @@ LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
am__DEPENDENCIES_2 = $(top_builddir)/libipset/libipset.la \
$(top_builddir)/libcork/libcork.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__append_3)
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) $(am__append_3)
am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
$(am__append_8)
libshadowsocks_libev_la_DEPENDENCIES = $(am__DEPENDENCIES_3)
am__libshadowsocks_libev_la_SOURCES_DIST = utils.c jconf.c json.c \
encrypt.c udprelay.c cache.c acl.c netutils.c local.c win32.c
@BUILD_WINCOMPAT_TRUE@am__objects_1 = \
encrypt.c udprelay.c cache.c acl.c netutils.c local.c http.c \
tls.c rule.c win32.c
am__objects_1 = libshadowsocks_libev_la-http.lo \
libshadowsocks_libev_la-tls.lo libshadowsocks_libev_la-rule.lo
@BUILD_WINCOMPAT_TRUE@am__objects_2 = \
@BUILD_WINCOMPAT_TRUE@ libshadowsocks_libev_la-win32.lo
am__objects_2 = libshadowsocks_libev_la-utils.lo \
am__objects_3 = libshadowsocks_libev_la-utils.lo \
libshadowsocks_libev_la-jconf.lo \
libshadowsocks_libev_la-json.lo \
libshadowsocks_libev_la-encrypt.lo \
@ -169,8 +172,9 @@ am__objects_2 = libshadowsocks_libev_la-utils.lo \
libshadowsocks_libev_la-cache.lo \
libshadowsocks_libev_la-acl.lo \
libshadowsocks_libev_la-netutils.lo \
libshadowsocks_libev_la-local.lo $(am__objects_1)
am_libshadowsocks_libev_la_OBJECTS = $(am__objects_2)
libshadowsocks_libev_la-local.lo $(am__objects_1) \
$(am__objects_2)
am_libshadowsocks_libev_la_OBJECTS = $(am__objects_3)
libshadowsocks_libev_la_OBJECTS = \
$(am_libshadowsocks_libev_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@ -186,14 +190,17 @@ libshadowsocks_libev_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
@BUILD_REDIRECTOR_TRUE@am__EXEEXT_2 = ss-redir$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
am__ss_local_SOURCES_DIST = utils.c jconf.c json.c encrypt.c \
udprelay.c cache.c acl.c netutils.c local.c win32.c
@BUILD_WINCOMPAT_TRUE@am__objects_3 = ss_local-win32.$(OBJEXT)
udprelay.c cache.c acl.c netutils.c local.c http.c tls.c \
rule.c win32.c
am__objects_4 = ss_local-http.$(OBJEXT) ss_local-tls.$(OBJEXT) \
ss_local-rule.$(OBJEXT)
@BUILD_WINCOMPAT_TRUE@am__objects_5 = ss_local-win32.$(OBJEXT)
am_ss_local_OBJECTS = ss_local-utils.$(OBJEXT) \
ss_local-jconf.$(OBJEXT) ss_local-json.$(OBJEXT) \
ss_local-encrypt.$(OBJEXT) ss_local-udprelay.$(OBJEXT) \
ss_local-cache.$(OBJEXT) ss_local-acl.$(OBJEXT) \
ss_local-netutils.$(OBJEXT) ss_local-local.$(OBJEXT) \
$(am__objects_3)
$(am__objects_4) $(am__objects_5)
ss_local_OBJECTS = $(am_ss_local_OBJECTS)
ss_local_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
$(am__append_8)
@ -209,7 +216,9 @@ ss_manager_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(ss_manager_CFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
am__ss_redir_SOURCES_DIST = utils.c jconf.c json.c encrypt.c \
netutils.c cache.c udprelay.c redir.c
netutils.c cache.c udprelay.c redir.c http.c tls.c rule.c
am__objects_6 = ss_redir-http.$(OBJEXT) ss_redir-tls.$(OBJEXT) \
ss_redir-rule.$(OBJEXT)
@BUILD_REDIRECTOR_TRUE@am_ss_redir_OBJECTS = ss_redir-utils.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ ss_redir-jconf.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ ss_redir-json.$(OBJEXT) \
@ -217,19 +226,22 @@ am__ss_redir_SOURCES_DIST = utils.c jconf.c json.c encrypt.c \
@BUILD_REDIRECTOR_TRUE@ ss_redir-netutils.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ ss_redir-cache.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ ss_redir-udprelay.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ ss_redir-redir.$(OBJEXT)
@BUILD_REDIRECTOR_TRUE@ ss_redir-redir.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ $(am__objects_6)
ss_redir_OBJECTS = $(am_ss_redir_OBJECTS)
@BUILD_REDIRECTOR_TRUE@ss_redir_DEPENDENCIES = $(am__DEPENDENCIES_2) \
@BUILD_REDIRECTOR_TRUE@ $(am__DEPENDENCIES_1) $(am__append_15)
ss_redir_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(ss_redir_CFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
am__objects_7 = ss_server-http.$(OBJEXT) ss_server-tls.$(OBJEXT) \
ss_server-rule.$(OBJEXT)
am_ss_server_OBJECTS = ss_server-utils.$(OBJEXT) \
ss_server-netutils.$(OBJEXT) ss_server-jconf.$(OBJEXT) \
ss_server-json.$(OBJEXT) ss_server-encrypt.$(OBJEXT) \
ss_server-udprelay.$(OBJEXT) ss_server-cache.$(OBJEXT) \
ss_server-acl.$(OBJEXT) ss_server-resolv.$(OBJEXT) \
ss_server-server.$(OBJEXT)
ss_server-server.$(OBJEXT) $(am__objects_7)
ss_server_OBJECTS = $(am_ss_server_OBJECTS)
ss_server_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
$(am__append_10)
@ -238,12 +250,12 @@ ss_server_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
am__ss_tunnel_SOURCES_DIST = utils.c jconf.c json.c encrypt.c \
udprelay.c cache.c netutils.c tunnel.c win32.c
@BUILD_WINCOMPAT_TRUE@am__objects_4 = ss_tunnel-win32.$(OBJEXT)
@BUILD_WINCOMPAT_TRUE@am__objects_8 = ss_tunnel-win32.$(OBJEXT)
am_ss_tunnel_OBJECTS = ss_tunnel-utils.$(OBJEXT) \
ss_tunnel-jconf.$(OBJEXT) ss_tunnel-json.$(OBJEXT) \
ss_tunnel-encrypt.$(OBJEXT) ss_tunnel-udprelay.$(OBJEXT) \
ss_tunnel-cache.$(OBJEXT) ss_tunnel-netutils.$(OBJEXT) \
ss_tunnel-tunnel.$(OBJEXT) $(am__objects_4)
ss_tunnel-tunnel.$(OBJEXT) $(am__objects_8)
ss_tunnel_OBJECTS = $(am_ss_tunnel_OBJECTS)
ss_tunnel_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
$(am__append_9)
@ -346,6 +358,7 @@ EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GZIP = @GZIP@
HAVE_LIBPCRE = @HAVE_LIBPCRE@
INET_NTOP_LIB = @INET_NTOP_LIB@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@ -355,11 +368,16 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBPCRE = @LIBPCRE@
LIBPCRE_CFLAGS = @LIBPCRE_CFLAGS@
LIBPCRE_LIBS = @LIBPCRE_LIBS@
LIBPCRE_PREFIX = @LIBPCRE_PREFIX@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LTLIBPCRE = @LTLIBPCRE@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
@ -379,6 +397,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
@ -449,12 +470,16 @@ AM_CFLAGS = -g -O2 -Wall -Werror -Wno-deprecated-declarations \
-fno-strict-aliasing -std=gnu99 -D_GNU_SOURCE \
$(PTHREAD_CFLAGS) $(am__append_1) \
-I$(top_srcdir)/libipset/include \
-I$(top_srcdir)/libcork/include
-I$(top_srcdir)/libcork/include $(LIBPCRE_CFLAGS)
SS_COMMON_LIBS = $(top_builddir)/libipset/libipset.la \
$(top_builddir)/libcork/libcork.la $(INET_NTOP_LIB) \
$(am__append_2) $(am__append_3)
$(LIBPCRE_LIBS) $(am__append_2) $(am__append_3)
sni_src = http.c \
tls.c \
rule.c
ss_local_SOURCES = utils.c jconf.c json.c encrypt.c udprelay.c cache.c \
acl.c netutils.c local.c $(am__append_11)
acl.c netutils.c local.c $(sni_src) $(am__append_11)
ss_tunnel_SOURCES = utils.c jconf.c json.c encrypt.c udprelay.c \
cache.c netutils.c tunnel.c $(am__append_12)
ss_server_SOURCES = utils.c \
@ -466,7 +491,8 @@ ss_server_SOURCES = utils.c \
cache.c \
acl.c \
resolv.c \
server.c
server.c \
$(sni_src)
ss_manager_SOURCES = utils.c \
jconf.c \
@ -489,7 +515,8 @@ ss_manager_CFLAGS = $(AM_CFLAGS) -DMODULE_MANAGER
@BUILD_REDIRECTOR_TRUE@ netutils.c \
@BUILD_REDIRECTOR_TRUE@ cache.c \
@BUILD_REDIRECTOR_TRUE@ udprelay.c \
@BUILD_REDIRECTOR_TRUE@ redir.c
@BUILD_REDIRECTOR_TRUE@ redir.c \
@BUILD_REDIRECTOR_TRUE@ $(sni_src)
@BUILD_REDIRECTOR_TRUE@ss_redir_CFLAGS = $(AM_CFLAGS) -DMODULE_REDIR
@BUILD_REDIRECTOR_TRUE@ss_redir_LDADD = $(SS_COMMON_LIBS) \
@ -686,20 +713,26 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-acl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-cache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-encrypt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-http.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-jconf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-json.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-local.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-netutils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-rule.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-tls.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-udprelay.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_libev_la-win32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-acl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-encrypt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-http.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-jconf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-json.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-local.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-netutils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-rule.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-tls.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-udprelay.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-utils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_local-win32.Po@am__quote@
@ -709,20 +742,26 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_manager-utils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-encrypt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-http.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-jconf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-json.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-netutils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-redir.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-rule.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-tls.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-udprelay.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_redir-utils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-acl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-encrypt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-http.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-jconf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-json.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-netutils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-resolv.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-rule.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-server.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-tls.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-udprelay.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_server-utils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-cache.Po@am__quote@
@ -822,6 +861,27 @@ libshadowsocks_libev_la-local.lo: local.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -c -o libshadowsocks_libev_la-local.lo `test -f 'local.c' || echo '$(srcdir)/'`local.c
libshadowsocks_libev_la-http.lo: http.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -MT libshadowsocks_libev_la-http.lo -MD -MP -MF $(DEPDIR)/libshadowsocks_libev_la-http.Tpo -c -o libshadowsocks_libev_la-http.lo `test -f 'http.c' || echo '$(srcdir)/'`http.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libshadowsocks_libev_la-http.Tpo $(DEPDIR)/libshadowsocks_libev_la-http.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='libshadowsocks_libev_la-http.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -c -o libshadowsocks_libev_la-http.lo `test -f 'http.c' || echo '$(srcdir)/'`http.c
libshadowsocks_libev_la-tls.lo: tls.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -MT libshadowsocks_libev_la-tls.lo -MD -MP -MF $(DEPDIR)/libshadowsocks_libev_la-tls.Tpo -c -o libshadowsocks_libev_la-tls.lo `test -f 'tls.c' || echo '$(srcdir)/'`tls.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libshadowsocks_libev_la-tls.Tpo $(DEPDIR)/libshadowsocks_libev_la-tls.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='libshadowsocks_libev_la-tls.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -c -o libshadowsocks_libev_la-tls.lo `test -f 'tls.c' || echo '$(srcdir)/'`tls.c
libshadowsocks_libev_la-rule.lo: rule.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -MT libshadowsocks_libev_la-rule.lo -MD -MP -MF $(DEPDIR)/libshadowsocks_libev_la-rule.Tpo -c -o libshadowsocks_libev_la-rule.lo `test -f 'rule.c' || echo '$(srcdir)/'`rule.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libshadowsocks_libev_la-rule.Tpo $(DEPDIR)/libshadowsocks_libev_la-rule.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rule.c' object='libshadowsocks_libev_la-rule.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -c -o libshadowsocks_libev_la-rule.lo `test -f 'rule.c' || echo '$(srcdir)/'`rule.c
libshadowsocks_libev_la-win32.lo: win32.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libshadowsocks_libev_la_CFLAGS) $(CFLAGS) -MT libshadowsocks_libev_la-win32.lo -MD -MP -MF $(DEPDIR)/libshadowsocks_libev_la-win32.Tpo -c -o libshadowsocks_libev_la-win32.lo `test -f 'win32.c' || echo '$(srcdir)/'`win32.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libshadowsocks_libev_la-win32.Tpo $(DEPDIR)/libshadowsocks_libev_la-win32.Plo
@ -955,6 +1015,48 @@ ss_local-local.obj: local.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-local.obj `if test -f 'local.c'; then $(CYGPATH_W) 'local.c'; else $(CYGPATH_W) '$(srcdir)/local.c'; fi`
ss_local-http.o: http.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-http.o -MD -MP -MF $(DEPDIR)/ss_local-http.Tpo -c -o ss_local-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-http.Tpo $(DEPDIR)/ss_local-http.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='ss_local-http.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c
ss_local-http.obj: http.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-http.obj -MD -MP -MF $(DEPDIR)/ss_local-http.Tpo -c -o ss_local-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-http.Tpo $(DEPDIR)/ss_local-http.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='ss_local-http.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi`
ss_local-tls.o: tls.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-tls.o -MD -MP -MF $(DEPDIR)/ss_local-tls.Tpo -c -o ss_local-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-tls.Tpo $(DEPDIR)/ss_local-tls.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='ss_local-tls.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c
ss_local-tls.obj: tls.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-tls.obj -MD -MP -MF $(DEPDIR)/ss_local-tls.Tpo -c -o ss_local-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-tls.Tpo $(DEPDIR)/ss_local-tls.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='ss_local-tls.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi`
ss_local-rule.o: rule.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-rule.o -MD -MP -MF $(DEPDIR)/ss_local-rule.Tpo -c -o ss_local-rule.o `test -f 'rule.c' || echo '$(srcdir)/'`rule.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-rule.Tpo $(DEPDIR)/ss_local-rule.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rule.c' object='ss_local-rule.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-rule.o `test -f 'rule.c' || echo '$(srcdir)/'`rule.c
ss_local-rule.obj: rule.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-rule.obj -MD -MP -MF $(DEPDIR)/ss_local-rule.Tpo -c -o ss_local-rule.obj `if test -f 'rule.c'; then $(CYGPATH_W) 'rule.c'; else $(CYGPATH_W) '$(srcdir)/rule.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-rule.Tpo $(DEPDIR)/ss_local-rule.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rule.c' object='ss_local-rule.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -c -o ss_local-rule.obj `if test -f 'rule.c'; then $(CYGPATH_W) 'rule.c'; else $(CYGPATH_W) '$(srcdir)/rule.c'; fi`
ss_local-win32.o: win32.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-win32.o -MD -MP -MF $(DEPDIR)/ss_local-win32.Tpo -c -o ss_local-win32.o `test -f 'win32.c' || echo '$(srcdir)/'`win32.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-win32.Tpo $(DEPDIR)/ss_local-win32.Po
@ -1137,6 +1239,48 @@ ss_redir-redir.obj: redir.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-redir.obj `if test -f 'redir.c'; then $(CYGPATH_W) 'redir.c'; else $(CYGPATH_W) '$(srcdir)/redir.c'; fi`
ss_redir-http.o: http.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-http.o -MD -MP -MF $(DEPDIR)/ss_redir-http.Tpo -c -o ss_redir-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-http.Tpo $(DEPDIR)/ss_redir-http.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='ss_redir-http.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c
ss_redir-http.obj: http.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-http.obj -MD -MP -MF $(DEPDIR)/ss_redir-http.Tpo -c -o ss_redir-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-http.Tpo $(DEPDIR)/ss_redir-http.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='ss_redir-http.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi`
ss_redir-tls.o: tls.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-tls.o -MD -MP -MF $(DEPDIR)/ss_redir-tls.Tpo -c -o ss_redir-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-tls.Tpo $(DEPDIR)/ss_redir-tls.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='ss_redir-tls.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c
ss_redir-tls.obj: tls.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-tls.obj -MD -MP -MF $(DEPDIR)/ss_redir-tls.Tpo -c -o ss_redir-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-tls.Tpo $(DEPDIR)/ss_redir-tls.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='ss_redir-tls.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi`
ss_redir-rule.o: rule.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-rule.o -MD -MP -MF $(DEPDIR)/ss_redir-rule.Tpo -c -o ss_redir-rule.o `test -f 'rule.c' || echo '$(srcdir)/'`rule.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-rule.Tpo $(DEPDIR)/ss_redir-rule.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rule.c' object='ss_redir-rule.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-rule.o `test -f 'rule.c' || echo '$(srcdir)/'`rule.c
ss_redir-rule.obj: rule.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -MT ss_redir-rule.obj -MD -MP -MF $(DEPDIR)/ss_redir-rule.Tpo -c -o ss_redir-rule.obj `if test -f 'rule.c'; then $(CYGPATH_W) 'rule.c'; else $(CYGPATH_W) '$(srcdir)/rule.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_redir-rule.Tpo $(DEPDIR)/ss_redir-rule.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rule.c' object='ss_redir-rule.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_redir_CFLAGS) $(CFLAGS) -c -o ss_redir-rule.obj `if test -f 'rule.c'; then $(CYGPATH_W) 'rule.c'; else $(CYGPATH_W) '$(srcdir)/rule.c'; fi`
ss_server-utils.o: utils.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-utils.o -MD -MP -MF $(DEPDIR)/ss_server-utils.Tpo -c -o ss_server-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-utils.Tpo $(DEPDIR)/ss_server-utils.Po
@ -1277,6 +1421,48 @@ ss_server-server.obj: server.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-server.obj `if test -f 'server.c'; then $(CYGPATH_W) 'server.c'; else $(CYGPATH_W) '$(srcdir)/server.c'; fi`
ss_server-http.o: http.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-http.o -MD -MP -MF $(DEPDIR)/ss_server-http.Tpo -c -o ss_server-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-http.Tpo $(DEPDIR)/ss_server-http.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='ss_server-http.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-http.o `test -f 'http.c' || echo '$(srcdir)/'`http.c
ss_server-http.obj: http.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-http.obj -MD -MP -MF $(DEPDIR)/ss_server-http.Tpo -c -o ss_server-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-http.Tpo $(DEPDIR)/ss_server-http.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http.c' object='ss_server-http.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-http.obj `if test -f 'http.c'; then $(CYGPATH_W) 'http.c'; else $(CYGPATH_W) '$(srcdir)/http.c'; fi`
ss_server-tls.o: tls.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-tls.o -MD -MP -MF $(DEPDIR)/ss_server-tls.Tpo -c -o ss_server-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-tls.Tpo $(DEPDIR)/ss_server-tls.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='ss_server-tls.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-tls.o `test -f 'tls.c' || echo '$(srcdir)/'`tls.c
ss_server-tls.obj: tls.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-tls.obj -MD -MP -MF $(DEPDIR)/ss_server-tls.Tpo -c -o ss_server-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-tls.Tpo $(DEPDIR)/ss_server-tls.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tls.c' object='ss_server-tls.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-tls.obj `if test -f 'tls.c'; then $(CYGPATH_W) 'tls.c'; else $(CYGPATH_W) '$(srcdir)/tls.c'; fi`
ss_server-rule.o: rule.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-rule.o -MD -MP -MF $(DEPDIR)/ss_server-rule.Tpo -c -o ss_server-rule.o `test -f 'rule.c' || echo '$(srcdir)/'`rule.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-rule.Tpo $(DEPDIR)/ss_server-rule.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rule.c' object='ss_server-rule.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-rule.o `test -f 'rule.c' || echo '$(srcdir)/'`rule.c
ss_server-rule.obj: rule.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -MT ss_server-rule.obj -MD -MP -MF $(DEPDIR)/ss_server-rule.Tpo -c -o ss_server-rule.obj `if test -f 'rule.c'; then $(CYGPATH_W) 'rule.c'; else $(CYGPATH_W) '$(srcdir)/rule.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_server-rule.Tpo $(DEPDIR)/ss_server-rule.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rule.c' object='ss_server-rule.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_server_CFLAGS) $(CFLAGS) -c -o ss_server-rule.obj `if test -f 'rule.c'; then $(CYGPATH_W) 'rule.c'; else $(CYGPATH_W) '$(srcdir)/rule.c'; fi`
ss_tunnel-utils.o: utils.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -MT ss_tunnel-utils.o -MD -MP -MF $(DEPDIR)/ss_tunnel-utils.Tpo -c -o ss_tunnel-utils.o `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_tunnel-utils.Tpo $(DEPDIR)/ss_tunnel-utils.Po

121
src/acl.c

@ -22,11 +22,18 @@
#include <ipset/ipset.h>
#include "rule.h"
#include "utils.h"
#include "acl.h"
static struct ip_set acl_ipv4_set;
static struct ip_set acl_ipv6_set;
static struct ip_set white_list_ipv4;
static struct ip_set white_list_ipv6;
static struct ip_set black_list_ipv4;
static struct ip_set black_list_ipv6;
rule_head_t black_list_rules;
rule_head_t white_list_rules;
static int acl_mode = BLACK_LIST;
@ -51,14 +58,22 @@ static void parse_addr_cidr(const char *str, char *host, int *cidr)
}
}
int init_acl(const char *path, int mode)
int init_acl(const char *path)
{
acl_mode = mode;
// initialize ipset
ipset_init_library();
ipset_init(&acl_ipv4_set);
ipset_init(&acl_ipv6_set);
ipset_init(&white_list_ipv4);
ipset_init(&white_list_ipv6);
ipset_init(&black_list_ipv4);
ipset_init(&black_list_ipv6);
STAILQ_INIT(&black_list_rules);
STAILQ_INIT(&white_list_rules);
struct ip_set *list_ipv4 = &black_list_ipv4;
struct ip_set *list_ipv6 = &black_list_ipv6;
rule_head_t *rules = &black_list_rules;
FILE *f = fopen(path, "r");
if (f == NULL) {
@ -75,6 +90,20 @@ int init_acl(const char *path, int mode)
line[len - 1] = '\0';
}
if (strcmp(line, "[black_list]") == 0
|| strcmp(line, "[bypass_list]") == 0) {
list_ipv4 = &black_list_ipv4;
list_ipv6 = &black_list_ipv6;
rules = &black_list_rules;
continue;
} else if (strcmp(line, "[white_list]") == 0
|| strcmp(line, "[proxy_list]") == 0) {
list_ipv4 = &white_list_ipv4;
list_ipv6 = &white_list_ipv6;
rules = &white_list_rules;
continue;
}
char host[257];
int cidr;
parse_addr_cidr(line, host, &cidr);
@ -84,17 +113,22 @@ int init_acl(const char *path, int mode)
if (!err) {
if (addr.version == 4) {
if (cidr >= 0) {
ipset_ipv4_add_network(&acl_ipv4_set, &(addr.ip.v4), cidr);
ipset_ipv4_add_network(list_ipv4, &(addr.ip.v4), cidr);
} else {
ipset_ipv4_add(&acl_ipv4_set, &(addr.ip.v4));
ipset_ipv4_add(list_ipv4, &(addr.ip.v4));
}
} else if (addr.version == 6) {
if (cidr >= 0) {
ipset_ipv6_add_network(&acl_ipv6_set, &(addr.ip.v6), cidr);
ipset_ipv6_add_network(list_ipv6, &(addr.ip.v6), cidr);
} else {
ipset_ipv6_add(&acl_ipv6_set, &(addr.ip.v6));
ipset_ipv6_add(list_ipv6, &(addr.ip.v6));
}
}
} else {
rule_t *rule = new_rule();
accept_rule_arg(rule, line);
init_rule(rule);
add_rule(rules, rule);
}
}
@ -103,33 +137,64 @@ int init_acl(const char *path, int mode)
return 0;
}
void free_rules(rule_head_t *rules)
{
rule_t *iter;
while ((iter = STAILQ_FIRST(rules)) != NULL)
remove_rule(rules, iter);
}
void free_acl(void)
{
ipset_done(&acl_ipv4_set);
ipset_done(&acl_ipv6_set);
ipset_done(&black_list_ipv4);
ipset_done(&black_list_ipv6);
ipset_done(&white_list_ipv4);
ipset_done(&white_list_ipv6);
free_rules(&black_list_rules);
free_rules(&white_list_rules);
}
int acl_get_mode(void)
int get_acl_mode(void)
{
return acl_mode;
}
int acl_match_ip(const char *ip)
void set_acl_mode(int mode)
{
acl_mode = mode;
}
/*
* Return 0, if not match.
* Return 1, if match black list.
* Return -1, if match white list.
*/
int acl_match_host(const char *host)
{
struct cork_ip addr;
int ret = cork_ip_init(&addr, ip);
if (ret) {
return 0;
int ret = 0;
int err = cork_ip_init(&addr, host);
if (err) {
int host_len = strlen(host);
if (lookup_rule(&black_list_rules, host, host_len) != NULL)
ret = 1;
else if (lookup_rule(&white_list_rules, host, host_len) != NULL)
ret = -1;
return ret;
}
if (addr.version == 4) {
ret = ipset_contains_ipv4(&acl_ipv4_set, &(addr.ip.v4));
if (ipset_contains_ipv4(&black_list_ipv4, &(addr.ip.v4)))
ret = 1;
else if (ipset_contains_ipv4(&white_list_ipv4, &(addr.ip.v4)))
ret = -1;
} else if (addr.version == 6) {
ret = ipset_contains_ipv6(&acl_ipv6_set, &(addr.ip.v6));
}
if (acl_mode == WHITE_LIST) {
ret = !ret;
if (ipset_contains_ipv6(&black_list_ipv6, &(addr.ip.v6)))
ret = 1;
else if (ipset_contains_ipv6(&white_list_ipv6, &(addr.ip.v6)))
ret = -1;
}
return ret;
@ -144,9 +209,9 @@ int acl_add_ip(const char *ip)
}
if (addr.version == 4) {
ipset_ipv4_add(&acl_ipv4_set, &(addr.ip.v4));
ipset_ipv4_add(&black_list_ipv4, &(addr.ip.v4));
} else if (addr.version == 6) {
ipset_ipv6_add(&acl_ipv6_set, &(addr.ip.v6));
ipset_ipv6_add(&black_list_ipv6, &(addr.ip.v6));
}
return 0;
@ -161,9 +226,9 @@ int acl_remove_ip(const char *ip)
}
if (addr.version == 4) {
ipset_ipv4_remove(&acl_ipv4_set, &(addr.ip.v4));
ipset_ipv4_remove(&black_list_ipv4, &(addr.ip.v4));
} else if (addr.version == 6) {
ipset_ipv6_remove(&acl_ipv6_set, &(addr.ip.v6));
ipset_ipv6_remove(&black_list_ipv6, &(addr.ip.v6));
}
return 0;

8
src/acl.h

@ -26,12 +26,14 @@
#define BLACK_LIST 0
#define WHITE_LIST 1
int init_acl(const char *path, int mode);
int init_acl(const char *path);
void free_acl(void);
int acl_get_mode(void);
int acl_match_ip(const char *ip);
int acl_match_host(const char *ip);
int acl_add_ip(const char *ip);
int acl_remove_ip(const char *ip);
int get_acl_mode(void);
void set_acl_mode(int mode);
#endif // _ACL_H

140
src/http.c

@ -0,0 +1,140 @@
/*
* Copyright (c) 2011 and 2012, Dustin Lundquist <dustin@null-ptr.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h> /* malloc() */
#include <string.h> /* strncpy() */
#include <strings.h> /* strncasecmp() */
#include <ctype.h> /* isblank() */
#include "http.h"
#include "protocol.h"
#define SERVER_NAME_LEN 256
static int parse_http_header(const char *, size_t, char **);
static int get_header(const char *, const char *, int, char **);
static int next_header(const char **, int *);
static const protocol_t http_protocol_st = {
.default_port = 80,
.parse_packet = &parse_http_header,
};
const protocol_t *const http_protocol = &http_protocol_st;
/*
* Parses a HTTP request for the Host: header
*
* Returns:
* >=0 - length of the hostname and updates *hostname
* caller is responsible for freeing *hostname
* -1 - Incomplete request
* -2 - No Host header included in this request
* -3 - Invalid hostname pointer
* -4 - malloc failure
* < -4 - Invalid HTTP request
*
*/
static int
parse_http_header(const char* data, size_t data_len, char **hostname) {
int result, i;
if (hostname == NULL)
return -3;
result = get_header("Host:", data, data_len, hostname);
if (result < 0)
return result;
/*
* if the user specifies the port in the request, it is included here.
* Host: example.com:80
* so we trim off port portion
*/
for (i = result - 1; i >= 0; i--)
if ((*hostname)[i] == ':') {
(*hostname)[i] = '\0';
result = i;
break;
}
return result;
}
static int
get_header(const char *header, const char *data, int data_len, char **value) {
int len, header_len;
header_len = strlen(header);
/* loop through headers stopping at first blank line */
while ((len = next_header(&data, &data_len)) != 0)
if (len > header_len && strncasecmp(header, data, header_len) == 0) {
/* Eat leading whitespace */
while (header_len < len && isblank(data[header_len]))
header_len++;
*value = malloc(len - header_len + 1);
if (*value == NULL)
return -4;
strncpy(*value, data + header_len, len - header_len);
(*value)[len - header_len] = '\0';
return len - header_len;
}
/* If there is no data left after reading all the headers then we do not
* have a complete HTTP request, there must be a blank line */
if (data_len == 0)
return -1;
return -2;
}
static int
next_header(const char **data, int *len) {
int header_len;
/* perhaps we can optimize this to reuse the value of header_len, rather
* than scanning twice.
* Walk our data stream until the end of the header */
while (*len > 2 && (*data)[0] != '\r' && (*data)[1] != '\n') {
(*len)--;
(*data)++;
}
/* advanced past the <CR><LF> pair */
*data += 2;
*len -= 2;
/* Find the length of the next header */
header_len = 0;
while (*len > header_len + 1
&& (*data)[header_len] != '\r'
&& (*data)[header_len + 1] != '\n')
header_len++;
return header_len;
}

34
src/http.h

@ -0,0 +1,34 @@
/*
* Copyright (c) 2011 and 2012, Dustin Lundquist <dustin@null-ptr.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HTTP_H
#define HTTP_H
#include <stdio.h>
#include "protocol.h"
const protocol_t *const http_protocol;
#endif

2
src/jconf.c

@ -207,7 +207,7 @@ jconf_t *read_jconf(const char *file)
else
LOGI("ignore unknown mode: %s, use tcp_only as fallback",
mode_str);
free(mode_str);
ss_free(mode_str);
} else if (strcmp(name, "mtu") == 0) {
conf.mtu = value->u.integer;
} else if (strcmp(name, "mptcp") == 0) {

222
src/local.c

@ -64,6 +64,8 @@
#include "utils.h"
#include "socks5.h"
#include "acl.h"
#include "http.h"
#include "tls.h"
#include "local.h"
#ifndef EAGAIN
@ -206,11 +208,12 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
if (remote == NULL) {
buf = server->buf;
} else {
buf = remote->buf;
}
r = recv(server->fd, buf->array, BUF_SIZE, 0);
r = recv(server->fd, buf->array + buf->len, BUF_SIZE - buf->len, 0);
if (r == 0) {
// connection closed
@ -231,7 +234,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
}
}
buf->len = r;
buf->len += r;
while (1) {
// local socks5 server
@ -344,6 +347,9 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
} else if (s <= (int)(remote->buf->len)) {
remote->buf->len -= s;
remote->buf->idx = s;
} else {
remote->buf->idx = 0;
remote->buf->len = 0;
}
// Just connected
@ -356,6 +362,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
exit(1);
#endif
}
} else {
int s = send(remote->fd, remote->buf->array, remote->buf->len, 0);
if (s == -1) {
@ -377,6 +384,9 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
ev_io_stop(EV_A_ & server_recv_ctx->io);
ev_io_start(EV_A_ & remote->send_ctx->io);
return;
} else {
remote->buf->idx = 0;
remote->buf->len = 0;
}
}
@ -397,10 +407,11 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
continue;
}
buf->len = 0;
return;
} else if (server->stage == 1) {
} else if (server->stage == 1 || server->stage == 2) {
struct socks5_request *request = (struct socks5_request *)buf->array;
struct sockaddr_in sock_addr;
memset(&sock_addr, 0, sizeof(sock_addr));
@ -427,16 +438,17 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
close_and_free_server(EV_A_ server);
return;
} else {
char host[257], port[16];
char host[257], ip[INET6_ADDRSTRLEN], port[16];
buffer_t ss_addr_to_send;
buffer_t *abuf = &ss_addr_to_send;
balloc(abuf, BUF_SIZE);
abuf->array[abuf->len++] = request->atyp;
int atyp = request->atyp;
// get remote addr and port
if (request->atyp == 1) {
if (atyp == 1) {
// IP V4
size_t in_addr_len = sizeof(struct in_addr);
memcpy(abuf->array + abuf->len, buf->array + 4, in_addr_len + 2);
@ -445,10 +457,10 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
if (acl || verbose) {
uint16_t p = ntohs(*(uint16_t *)(buf->array + 4 + in_addr_len));
dns_ntop(AF_INET, (const void *)(buf->array + 4),
host, INET_ADDRSTRLEN);
ip, INET_ADDRSTRLEN);
sprintf(port, "%d", p);
}
} else if (request->atyp == 3) {
} else if (atyp == 3) {
// Domain name
uint8_t name_len = *(uint8_t *)(buf->array + 4);
abuf->array[abuf->len++] = name_len;
@ -462,7 +474,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
host[name_len] = '\0';
sprintf(port, "%d", p);
}
} else if (request->atyp == 4) {
} else if (atyp == 4) {
// IP V6
size_t in6_addr_len = sizeof(struct in6_addr);
memcpy(abuf->array + abuf->len, buf->array + 4, in6_addr_len + 2);
@ -471,7 +483,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
if (acl || verbose) {
uint16_t p = ntohs(*(uint16_t *)(buf->array + 4 + in6_addr_len));
dns_ntop(AF_INET6, (const void *)(buf->array + 4),
host, INET6_ADDRSTRLEN);
ip, INET6_ADDRSTRLEN);
sprintf(port, "%d", p);
}
} else {
@ -482,31 +494,147 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
return;
}
if (server->stage == 1) {
// Fake reply
struct socks5_response response;
response.ver = SVERSION;
response.rep = 0;
response.rsv = 0;
response.atyp = 1;
buffer_t resp_to_send;
buffer_t *resp_buf = &resp_to_send;
balloc(resp_buf, BUF_SIZE);
memcpy(resp_buf->array, &response, sizeof(struct socks5_response));
memcpy(resp_buf->array + sizeof(struct socks5_response),
&sock_addr.sin_addr, sizeof(sock_addr.sin_addr));
memcpy(resp_buf->array + sizeof(struct socks5_response) +
sizeof(sock_addr.sin_addr),
&sock_addr.sin_port, sizeof(sock_addr.sin_port));
int reply_size = sizeof(struct socks5_response) +
sizeof(sock_addr.sin_addr) + sizeof(sock_addr.sin_port);
int s = send(server->fd, resp_buf->array, reply_size, 0);
bfree(resp_buf);
if (s < reply_size) {
LOGE("failed to send fake reply");
bfree(abuf);
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
}
if (udp_assc) {
bfree(abuf);
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
}
}
size_t abuf_len = abuf->len;
int sni_detected = 0;
if (atyp == 1 || atyp == 4) {
char *hostname;
uint16_t p = ntohs(*(uint16_t *)(abuf->array + abuf->len - 2));
int ret = 0;
if (p == http_protocol->default_port)
ret = http_protocol->parse_packet(buf->array + 3 + abuf->len,
buf->len - 3 - abuf->len, &hostname);
else if (p == tls_protocol->default_port)
ret = tls_protocol->parse_packet(buf->array + 3 + abuf->len,
buf->len - 3 - abuf->len, &hostname);
if (ret == -1 || ret == -2) {
server->stage = 2;
bfree(abuf);
return;
} else if (ret > 0) {
sni_detected = 1;
// Reconstruct address buffer
abuf->len = 0;
abuf->array[abuf->len++] = 3;
abuf->array[abuf->len++] = ret;
memcpy(abuf->array + abuf->len, hostname, ret);
abuf->len += ret;
p = htons(p);
memcpy(abuf->array + abuf->len, &p, 2);
abuf->len += 2;
if (acl || verbose) {
memcpy(host, hostname, ret);
host[ret] = '\0';
}
ss_free(hostname);
}
}
server->stage = 5;
buf->len -= (3 + abuf->len);
buf->len -= (3 + abuf_len);
if (buf->len > 0) {
memmove(buf->array, buf->array + 3 + abuf->len, buf->len);
memmove(buf->array, buf->array + 3 + abuf_len, buf->len);
}
if (verbose) {
if (request->atyp == 4)
LOGI("connect to [%s]:%s", host, port);
else
if (sni_detected || atyp == 3)
LOGI("connect to %s:%s", host, port);
else if (atyp == 1)
LOGI("connect to %s:%s", ip, port);
else if (atyp == 4)
LOGI("connect to [%s]:%s", ip, port);
}
if ((acl && (request->atyp == 1 || request->atyp == 4) && acl_match_ip(host))) {
if (verbose) {
LOGI("bypass %s:%s", host, port);
if (acl) {
int host_match = acl_match_host(host);
int ip_match = acl_match_host(ip);
int bypass = get_acl_mode() == WHITE_LIST;
if (get_acl_mode() == BLACK_LIST) {
if (ip_match > 0) bypass = 1; // bypass IPs in black list
if (host_match > 0) bypass = 1; // bypass hostnames in black list
else if (host_match < 0) bypass = 0; // proxy hostnames in white list
} else if (get_acl_mode() == WHITE_LIST) {
if (ip_match < 0) bypass = 0; // proxy IPs in white list
if (host_match < 0) bypass = 0; // proxy hostnames in white list
else if (host_match > 0) bypass = 1; // bypass hostnames in black list
}
struct sockaddr_storage storage;
memset(&storage, 0, sizeof(struct sockaddr_storage));
if (get_sockaddr(host, port, &storage, 0) != -1) {
remote = create_remote(server->listener, (struct sockaddr *)&storage);
remote->direct = 1;
if (bypass) {
if (verbose) {
if (sni_detected || atyp == 3)
LOGI("bypass %s:%s", host, port);
else if (atyp == 1)
LOGI("bypass %s:%s", ip, port);
else if (atyp == 4)
LOGI("bypass [%s]:%s", ip, port);
}
struct sockaddr_storage storage;
int err;
memset(&storage, 0, sizeof(struct sockaddr_storage));
if (atyp == 1 || atyp == 4) {
err = get_sockaddr(ip, port, &storage, 0);
} else {
err = get_sockaddr(host, port, &storage, 1);
}
if (err != -1) {
remote = create_remote(server->listener, (struct sockaddr *)&storage);
remote->direct = 1;
}
}
} else {
}
// Not match ACL
if (remote == NULL) {
remote = create_remote(server->listener, NULL);
}
@ -545,37 +673,6 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
bfree(abuf);
}
// Fake reply
struct socks5_response response;
response.ver = SVERSION;
response.rep = 0;
response.rsv = 0;
response.atyp = 1;
memcpy(server->buf->array, &response, sizeof(struct socks5_response));
memcpy(server->buf->array + sizeof(struct socks5_response),
&sock_addr.sin_addr, sizeof(sock_addr.sin_addr));
memcpy(server->buf->array + sizeof(struct socks5_response) +
sizeof(sock_addr.sin_addr),
&sock_addr.sin_port, sizeof(sock_addr.sin_port));
int reply_size = sizeof(struct socks5_response) +
sizeof(sock_addr.sin_addr) +
sizeof(sock_addr.sin_port);
int s = send(server->fd, server->buf->array, reply_size, 0);
if (s < reply_size) {
LOGE("failed to send fake reply");
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
}
if (udp_assc) {
close_and_free_remote(EV_A_ remote);
close_and_free_server(EV_A_ server);
return;
}
}
}
}
@ -1030,10 +1127,10 @@ int main(int argc, char **argv)
USE_TTY();
#ifdef ANDROID
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:P:huUvVA",
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:P:huUvwVA",
long_options, &option_index)) != -1) {
#else
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:huUvA",
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:huUvwA",
long_options, &option_index)) != -1) {
#endif
switch (c) {
@ -1042,7 +1139,7 @@ int main(int argc, char **argv)
fast_open = 1;
} else if (option_index == 1) {
LOGI("initializing acl...");
acl = !init_acl(optarg, BLACK_LIST);
acl = !init_acl(optarg);
} else if (option_index == 2) {
mtu = atoi(optarg);
LOGI("set MTU to %d", mtu);
@ -1111,6 +1208,9 @@ int main(int argc, char **argv)
case 'A':
auth = 1;
break;
case 'w':
set_acl_mode(WHITE_LIST);
break;
#ifdef ANDROID
case 'V':
vpn = 1;
@ -1371,7 +1471,11 @@ int start_ss_local_server(profile_t profile)
USE_LOGFILE(log);
if (profile.acl != NULL) {
acl = !init_acl(profile.acl, BLACK_LIST);
acl = !init_acl(profile.acl);
}
if (profile.white_list) {
set_acl_mode(WHITE_LIST);
}
if (local_addr == NULL) {

4
src/local.h

@ -28,6 +28,7 @@
#include "encrypt.h"
#include "jconf.h"
#include "protocol.h"
#include "common.h"
@ -50,7 +51,6 @@ typedef struct server_ctx {
typedef struct server {
int fd;
buffer_t *buf;
char stage;
struct enc_ctx *e_ctx;
struct enc_ctx *d_ctx;
@ -59,6 +59,8 @@ typedef struct server {
struct listen_ctx *listener;
struct remote *remote;
buffer_t *buf;
struct cork_dllist_item entries;
} server_t;

26
src/manager.c

@ -103,7 +103,7 @@ static void build_config(char *prefix, struct server *server)
if (verbose) {
LOGE("unable to open config file");
}
free(path);
ss_free(path);
return;
}
fprintf(f, "{\n");
@ -111,7 +111,7 @@ static void build_config(char *prefix, struct server *server)
fprintf(f, "\"password\":\"%s\",\n", server->password);
fprintf(f, "}\n");
fclose(f);
free(path);
ss_free(path);
}
static char *construct_command_line(struct manager_ctx *manager, struct server *server)
@ -314,7 +314,7 @@ static void kill_server(char *prefix, char *pid_file)
if (verbose) {
LOGE("unable to open pid file");
}
free(path);
ss_free(path);
return;
}
if (fscanf(f, "%d", &pid) != EOF) {
@ -322,7 +322,7 @@ static void kill_server(char *prefix, char *pid_file)
}
fclose(f);
remove(path);
free(path);
ss_free(path);
}
static void stop_server(char *prefix, char *port)
@ -336,14 +336,14 @@ static void stop_server(char *prefix, char *port)
if (verbose) {
LOGE("unable to open pid file");
}
free(path);
ss_free(path);
return;
}
if (fscanf(f, "%d", &pid) != EOF) {
kill(pid, SIGTERM);
}
fclose(f);
free(path);
ss_free(path);
}
static void remove_server(char *prefix, char *port)
@ -819,7 +819,7 @@ int main(int argc, char **argv)
int err = mkdir(working_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (err != 0 && errno != EEXIST) {
ERROR("mkdir");
free(working_dir);
ss_free(working_dir);
FATAL("unable to create working directory");
}
@ -837,7 +837,7 @@ int main(int argc, char **argv)
}
closedir (dp);
} else {
free(working_dir);
ss_free(working_dir);
FATAL("Couldn't open the directory");
}
@ -860,7 +860,7 @@ int main(int argc, char **argv)
struct sockaddr_un svaddr;
sfd = socket(AF_UNIX, SOCK_DGRAM, 0); /* Create server socket */
if (sfd == -1) {
free(working_dir);
ss_free(working_dir);
FATAL("socket");
}
@ -868,7 +868,7 @@ int main(int argc, char **argv)
if (remove(manager_address) == -1 && errno != ENOENT) {
ERROR("bind");
free(working_dir);
ss_free(working_dir);
exit(EXIT_FAILURE);
}
@ -878,13 +878,13 @@ int main(int argc, char **argv)
if (bind(sfd, (struct sockaddr *)&svaddr, sizeof(struct sockaddr_un)) == -1) {
ERROR("bind");
free(working_dir);
ss_free(working_dir);
exit(EXIT_FAILURE);
}
} else {
sfd = create_server_socket(ip_addr.host, ip_addr.port);
if (sfd == -1) {
free(working_dir);
ss_free(working_dir);
FATAL("socket");
}
}
@ -917,7 +917,7 @@ int main(int argc, char **argv)
ev_signal_stop(EV_DEFAULT, &sigint_watcher);
ev_signal_stop(EV_DEFAULT, &sigterm_watcher);
free(working_dir);
ss_free(working_dir);
return 0;
}

34
src/protocol.h

@ -0,0 +1,34 @@
/*
* Copyright (c) 2014, Dustin Lundquist <dustin@null-ptr.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PROTOCOL_H
#define PROTOCOL_H
typedef struct protocol {
const int default_port;
int (*const parse_packet)(const char*, size_t, char **);
} protocol_t;
#endif

58
src/redir.c

@ -46,6 +46,8 @@
#include "config.h"
#endif
#include "http.h"
#include "tls.h"
#include "netutils.h"
#include "utils.h"
#include "common.h"
@ -173,7 +175,8 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
server_t *server = server_recv_ctx->server;
remote_t *remote = server->remote;
ssize_t r = recv(server->fd, remote->buf->array, BUF_SIZE, 0);
ssize_t r = recv(server->fd, remote->buf->array + remote->buf->len,
BUF_SIZE - remote->buf->len, 0);
if (r == 0) {
// connection closed
@ -193,6 +196,8 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
}
}
remote->buf->len += r;
if (verbose) {
uint16_t port = 0;
char ipstr[INET6_ADDRSTRLEN];
@ -210,16 +215,33 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
port = ntohs(sa->sin6_port);
}
LOGI("redir to %s:%d, len=%zd", ipstr, port, r);
LOGI("redir to %s:%d, len=%zd, recv=%zd", ipstr, port, remote->buf->len, r);
}
remote->buf->len = r;
if (auth) {
ss_gen_hash(remote->buf, &remote->counter, server->e_ctx, BUF_SIZE);
}
if (!remote->send_ctx->connected) {
// SNI
int ret = 0;
uint16_t port = 0;
if (AF_INET6 == server->destaddr.ss_family) { // IPv6
port = ntohs(((struct sockaddr_in6 *)&(server->destaddr))->sin6_port);
} else { // IPv4
port = ntohs(((struct sockaddr_in *)&(server->destaddr))->sin_port);
}
if (port == http_protocol->default_port)
ret = http_protocol->parse_packet(remote->buf->array,
remote->buf->len, &server->hostname);
else if (port == tls_protocol->default_port)
ret = tls_protocol->parse_packet(remote->buf->array,
remote->buf->len, &server->hostname);
if (ret > 0) {
server->hostname_len = ret;
}
ev_io_stop(EV_A_ & server_recv_ctx->io);
ev_io_start(EV_A_ & remote->send_ctx->io);
return;
@ -255,6 +277,9 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
ev_io_stop(EV_A_ & server_recv_ctx->io);
ev_io_start(EV_A_ & remote->send_ctx->io);
return;
} else {
remote->buf->idx = 0;
remote->buf->len = 0;
}
}
@ -389,7 +414,23 @@ static void remote_send_cb(EV_P_ ev_io *w, int revents)
buffer_t *abuf = &ss_addr_to_send;
balloc(abuf, BUF_SIZE);
if (AF_INET6 == server->destaddr.ss_family) { // IPv6
if (server->hostname_len > 0) { // HTTP/SNI
uint16_t port;
if (AF_INET6 == server->destaddr.ss_family) { // IPv6
port = (((struct sockaddr_in6 *)&(server->destaddr))->sin6_port);
} else { // IPv4
port = (((struct sockaddr_in *)&(server->destaddr))->sin_port);
}
abuf->array[abuf->len++] = 3; // Type 3 is hostname
abuf->array[abuf->len++] = server->hostname_len;
memcpy(abuf->array + abuf->len, server->hostname, server->hostname_len);
abuf->len += server->hostname_len;
memcpy(abuf->array + abuf->len, &port, 2);
LOGI("Dest: %s:%d", server->hostname, ntohs(port));
} else if (AF_INET6 == server->destaddr.ss_family) { // IPv6
abuf->array[abuf->len++] = 4; // Type 4 is IPv6 address
size_t in6_addr_len = sizeof(struct in6_addr);
@ -410,6 +451,7 @@ static void remote_send_cb(EV_P_ ev_io *w, int revents)
memcpy(abuf->array + abuf->len,
&((struct sockaddr_in *)&(server->destaddr))->sin_port, 2);
}
abuf->len += 2;
if (auth) {
@ -540,6 +582,9 @@ static server_t *new_server(int fd, int method)
server->send_ctx->server = server;
server->send_ctx->connected = 0;
server->hostname = NULL;
server->hostname_len = 0;
if (method) {
server->e_ctx = ss_malloc(sizeof(enc_ctx_t));
server->d_ctx = ss_malloc(sizeof(enc_ctx_t));
@ -561,6 +606,9 @@ static server_t *new_server(int fd, int method)
static void free_server(server_t *server)
{
if (server != NULL) {
if (server->hostname != NULL) {
ss_free(server->hostname);
}
if (server->remote != NULL) {
server->remote->server = NULL;
}

3
src/redir.h

@ -52,6 +52,9 @@ typedef struct server {
struct server_ctx *recv_ctx;
struct server_ctx *send_ctx;
struct remote *remote;
char *hostname;
size_t hostname_len;
} server_t;
typedef struct remote_ctx {

122
src/rule.c

@ -0,0 +1,122 @@
/*
* Copyright (c) 2011 and 2012, Dustin Lundquist <dustin@null-ptr.net>
* Copyright (c) 2011 Manuel Kasper <mk@neon1.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <sys/queue.h>
#include <pcre.h>
#include "rule.h"
#include "utils.h"
static void free_rule(rule_t *);
rule_t *
new_rule() {
rule_t *rule;
rule = calloc(1, sizeof(rule_t));
if (rule == NULL) {
ERROR("malloc");
return NULL;
}
return rule;
}
int
accept_rule_arg(rule_t *rule, const char *arg) {
if (rule->pattern == NULL) {
rule->pattern = strdup(arg);
if (rule->pattern == NULL) {
ERROR("strdup failed");
return -1;
}
} else {
LOGE("Unexpected table rule argument: %s", arg);
return -1;
}
return 1;
}
void
add_rule(rule_head_t *rules, rule_t *rule) {
STAILQ_INSERT_TAIL(rules, rule, entries);
}
int
init_rule(rule_t *rule) {
if (rule->pattern_re == NULL) {
const char *reerr;
int reerroffset;
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);
return 0;
}
}
return 1;
}
rule_t *
lookup_rule(const rule_head_t *head, const char *name, size_t name_len) {
rule_t *iter;
if (name == NULL) {
name = "";
name_len = 0;
}
STAILQ_FOREACH(iter, head, entries) {
if (pcre_exec(iter->pattern_re, NULL,
name, name_len, 0, 0, NULL, 0) >= 0)
return iter;
}
return NULL;
}
void
remove_rule(rule_head_t *head, rule_t *rule) {
STAILQ_REMOVE(head, rule, rule, entries);
free_rule(rule);
}
static void
free_rule(rule_t *rule) {
if (rule == NULL)
return;
ss_free(rule->pattern);
if (rule->pattern_re != NULL)
pcre_free(rule->pattern_re);
ss_free(rule);
}

53
src/rule.h

@ -0,0 +1,53 @@
/*
* Copyright (c) 2011 and 2012, Dustin Lundquist <dustin@null-ptr.net>
* Copyright (c) 2011 Manuel Kasper <mk@neon1.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BACKEND_H
#define BACKEND_H
#include <sys/queue.h>
#include <pcre.h>
STAILQ_HEAD(rule_head, rule);
typedef struct rule_head rule_head_t;
typedef struct rule {
char *pattern;
/* Runtime fields */
pcre *pattern_re;
STAILQ_ENTRY(rule) entries;
} rule_t;
void add_rule(rule_head_t *, rule_t *);
int init_rule(rule_t *);
rule_t *lookup_rule(const rule_head_t *, const char *, size_t);
void remove_rule(rule_head_t *, rule_t *);
rule_t *new_rule();
int accept_rule_arg(rule_t *, const char *);
#endif

12
src/server.c

@ -110,7 +110,6 @@ static int is_header_complete(const buffer_t *buf);
int verbose = 0;
static int white_list = 0;
static int acl = 0;
static int mode = TCP_ONLY;
static int auth = 0;
@ -730,7 +729,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
if (peer_name) {
LOGE("authentication error from %s", peer_name);
if (acl) {
if (acl_get_mode() == BLACK_LIST) {
if (get_acl_mode() == BLACK_LIST) {
// Auto ban enabled only in black list mode
acl_add_ip(peer_name);
LOGE("add %s to the black list", peer_name);
@ -1403,7 +1402,7 @@ static void accept_cb(EV_P_ ev_io *w, int revents)
if (acl) {
char *peer_name = get_peer_name(serverfd);
if (peer_name != NULL && acl_match_ip(peer_name)) {
if (peer_name != NULL && acl_match_host(peer_name)) {
if (verbose)
LOGI("Access denied from %s", peer_name);
close(serverfd);
@ -1439,7 +1438,6 @@ int main(int argc, char **argv)
char *method = NULL;
char *pid_path = NULL;
char *conf_path = NULL;
char *acl_path = NULL;
char *iface = NULL;
int server_num = 0;
@ -1471,8 +1469,7 @@ int main(int argc, char **argv)
fast_open = 1;
} else if (option_index == 1) {
LOGI("initializing acl...");
acl = 1;
acl_path = optarg;
acl = !init_acl(optarg);
} else if (option_index == 2) {
manager_address = optarg;
} else if (option_index == 3) {
@ -1545,7 +1542,7 @@ int main(int argc, char **argv)
auth = 1;
break;
case 'w':
white_list = 1;
set_acl_mode(WHITE_LIST);
break;
case '6':
ipv6first = 1;
@ -1563,7 +1560,6 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
acl = acl ? !init_acl(acl_path, white_list) : 0;
if (argc == 1) {
if (conf_path == NULL) {

1
src/shadowsocks.h

@ -40,6 +40,7 @@ typedef struct {
int auth; // enable one-time authentication
int mtu; // MTU of interface
int mptcp; // enable multipath TCP
int white_list; // enable white list
int verbose; // verbose mode
} profile_t;

243
src/tls.c

@ -0,0 +1,243 @@
/*
* Copyright (c) 2011 and 2012, Dustin Lundquist <dustin@null-ptr.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This is a minimal TLS implementation intended only to parse the server name
* extension. This was created based primarily on Wireshark dissection of a
* TLS handshake and RFC4366.
*/
#include <stdio.h>
#include <stdlib.h> /* malloc() */
#include <string.h> /* strncpy() */
#include <sys/socket.h>
#include "tls.h"
#include "protocol.h"
#include "utils.h"
#define SERVER_NAME_LEN 256
#define TLS_HEADER_LEN 5
#define TLS_HANDSHAKE_CONTENT_TYPE 0x16
#define TLS_HANDSHAKE_TYPE_CLIENT_HELLO 0x01
#ifndef MIN
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
#endif
static int parse_tls_header(const char *, size_t, char **);
static int parse_extensions(const char *, size_t, char **);
static int parse_server_name_extension(const char *, size_t, char **);
static const protocol_t tls_protocol_st = {
.default_port = 443,
.parse_packet = &parse_tls_header,
};
const protocol_t *const tls_protocol = &tls_protocol_st;
/* Parse a TLS packet for the Server Name Indication extension in the client
* hello handshake, returning the first servername found (pointer to static
* array)
*
* Returns:
* >=0 - length of the hostname and updates *hostname
* caller is responsible for freeing *hostname
* -1 - Incomplete request
* -2 - No Host header included in this request
* -3 - Invalid hostname pointer
* -4 - malloc failure
* < -4 - Invalid TLS client hello
*/
static int
parse_tls_header(const char *data, size_t data_len, char **hostname) {
char tls_content_type;
char tls_version_major;
char tls_version_minor;
size_t pos = TLS_HEADER_LEN;
size_t len;
if (hostname == NULL)
return -3;
/* Check that our TCP payload is at least large enough for a TLS header */
if (data_len < TLS_HEADER_LEN)
return -1;
/* SSL 2.0 compatible Client Hello
*
* High bit of first byte (length) and content type is Client Hello
*
* See RFC5246 Appendix E.2
*/
if (data[0] & 0x80 && data[2] == 1) {
LOGI("Received SSL 2.0 Client Hello which can not support SNI.");
return -2;
}
tls_content_type = data[0];
if (tls_content_type != TLS_HANDSHAKE_CONTENT_TYPE) {
LOGI("Request did not begin with TLS handshake.");
return -5;
}
tls_version_major = data[1];
tls_version_minor = data[2];
if (tls_version_major < 3) {
LOGI("Received SSL %d.%d handshake which can not support SNI.",
tls_version_major, tls_version_minor);
return -2;
}
/* TLS record length */
len = ((unsigned char)data[3] << 8) +
(unsigned char)data[4] + TLS_HEADER_LEN;
data_len = MIN(data_len, len);
/* Check we received entire TLS record length */
if (data_len < len)
return -1;
/*
* Handshake
*/
if (pos + 1 > data_len) {
return -5;
}
if (data[pos] != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) {
LOGI("Not a client hello");
return -5;
}
/* Skip past fixed length records:
1 Handshake Type
3 Length
2 Version (again)
32 Random
to Session ID Length
*/
pos += 38;
/* Session ID */
if (pos + 1 > data_len)
return -5;
len = (unsigned char)data[pos];
pos += 1 + len;
/* Cipher Suites */
if (pos + 2 > data_len)
return -5;
len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1];
pos += 2 + len;
/* Compression Methods */
if (pos + 1 > data_len)
return -5;
len = (unsigned char)data[pos];
pos += 1 + len;
if (pos == data_len && tls_version_major == 3 && tls_version_minor == 0) {
LOGI("Received SSL 3.0 handshake without extensions");
return -2;
}
/* Extensions */
if (pos + 2 > data_len)
return -5;
len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1];
pos += 2;
if (pos + len > data_len)
return -5;
return parse_extensions(data + pos, len, hostname);
}
static int
parse_extensions(const char *data, size_t data_len, char **hostname) {
size_t pos = 0;
size_t len;
/* Parse each 4 bytes for the extension header */
while (pos + 4 <= data_len) {
/* Extension Length */
len = ((unsigned char)data[pos + 2] << 8) +
(unsigned char)data[pos + 3];
/* Check if it's a server name extension */
if (data[pos] == 0x00 && data[pos + 1] == 0x00) {
/* There can be only one extension of each type, so we break
our state and move p to beinnging of the extension here */
if (pos + 4 + len > data_len)
return -5;
return parse_server_name_extension(data + pos + 4, len, hostname);
}
pos += 4 + len; /* Advance to the next extension header */
}
/* Check we ended where we expected to */
if (pos != data_len)
return -5;
return -2;
}
static int
parse_server_name_extension(const char *data, size_t data_len,
char **hostname) {
size_t pos = 2; /* skip server name list length */
size_t len;
while (pos + 3 < data_len) {
len = ((unsigned char)data[pos + 1] << 8) +
(unsigned char)data[pos + 2];
if (pos + 3 + len > data_len)
return -5;
switch (data[pos]) { /* name type */
case 0x00: /* host_name */
*hostname = malloc(len + 1);
if (*hostname == NULL) {
ERROR("malloc() failure");
return -4;
}
strncpy(*hostname, data + pos + 3, len);
(*hostname)[len] = '\0';
return len;
default:
LOGI("Unknown server name extension name type: %d",
data[pos]);
}
pos += 3 + len;
}
/* Check we ended where we expected to */
if (pos != data_len)
return -5;
return -2;
}

33
src/tls.h

@ -0,0 +1,33 @@
/*
* Copyright (c) 2011 and 2012, Dustin Lundquist <dustin@null-ptr.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TLS_H
#define TLS_H
#include "protocol.h"
const protocol_t *const tls_protocol;
#endif
Loading…
Cancel
Save