Browse Source

Avoid getaddrinfo() in the main loop

pull/215/head
Max Lv 10 years ago
committed by Max Lv
parent
commit
40e9be0021
20 changed files with 319 additions and 191 deletions
  1. 20
      configure
  2. 2
      configure.ac
  3. 6
      debian/changelog
  4. 2
      openwrt/Makefile
  5. 4
      src/Makefile.am
  6. 73
      src/Makefile.in
  7. 2
      src/common.h
  8. 120
      src/local.c
  9. 6
      src/local.h
  10. 110
      src/netutils.c
  11. 24
      src/netutils.h
  12. 41
      src/redir.c
  13. 3
      src/redir.h
  14. 48
      src/tunnel.c
  15. 3
      src/tunnel.h
  16. 36
      src/udprelay.c
  17. 4
      src/udprelay.h
  18. 4
      src/utils.c
  19. 1
      src/win32.c
  20. 1
      src/win32.h

20
configure

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for shadowsocks-libev 2.0.4.
# Generated by GNU Autoconf 2.69 for shadowsocks-libev 2.0.5.
#
# Report bugs to <max.c.lv@gmail.com>.
#
@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='shadowsocks-libev'
PACKAGE_TARNAME='shadowsocks-libev'
PACKAGE_VERSION='2.0.4'
PACKAGE_STRING='shadowsocks-libev 2.0.4'
PACKAGE_VERSION='2.0.5'
PACKAGE_STRING='shadowsocks-libev 2.0.5'
PACKAGE_BUGREPORT='max.c.lv@gmail.com'
PACKAGE_URL=''
@ -1336,7 +1336,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures shadowsocks-libev 2.0.4 to adapt to many kinds of systems.
\`configure' configures shadowsocks-libev 2.0.5 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1407,7 +1407,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of shadowsocks-libev 2.0.4:";;
short | recursive ) echo "Configuration of shadowsocks-libev 2.0.5:";;
esac
cat <<\_ACEOF
@ -1528,7 +1528,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
shadowsocks-libev configure 2.0.4
shadowsocks-libev configure 2.0.5
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -2051,7 +2051,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by shadowsocks-libev $as_me 2.0.4, which was
It was created by shadowsocks-libev $as_me 2.0.5, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -2872,7 +2872,7 @@ fi
# Define the identity of the package.
PACKAGE='shadowsocks-libev'
VERSION='2.0.4'
VERSION='2.0.5'
cat >>confdefs.h <<_ACEOF
@ -15636,7 +15636,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by shadowsocks-libev $as_me 2.0.4, which was
This file was extended by shadowsocks-libev $as_me 2.0.5, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -15702,7 +15702,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
shadowsocks-libev config.status 2.0.4
shadowsocks-libev config.status 2.0.5
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

2
configure.ac

@ -2,7 +2,7 @@ dnl -*- Autoconf -*-
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.67])
AC_INIT([shadowsocks-libev], [2.0.4], [max.c.lv@gmail.com])
AC_INIT([shadowsocks-libev], [2.0.5], [max.c.lv@gmail.com])
AC_CONFIG_SRCDIR([src/encrypt.c])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_AUX_DIR(auto)

6
debian/changelog

@ -1,3 +1,9 @@
shadowsocks-libev (2.0.5-1) unstable; urgency=low
* Refine local, tunnel, and redir modes.
-- Max Lv <max.c.lv@gmail.com> Mon, 12 Jan 2015 12:39:05 +0800
shadowsocks-libev (2.0.4-1) unstable; urgency=low
* Fix building issues with MinGW32.

2
openwrt/Makefile

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=shadowsocks-libev
PKG_VERSION:=2.0.4
PKG_VERSION:=2.0.5
PKG_RELEASE=$(PKG_SOURCE_VERSION)
PKG_SOURCE_URL:=https://github.com/shadowsocks/shadowsocks-libev/archive

4
src/Makefile.am

@ -27,6 +27,7 @@ ss_local_SOURCES = utils.c \
udprelay.c \
cache.c \
acl.c \
netutils.c \
local.c
ss_tunnel_SOURCES = utils.c \
@ -35,6 +36,7 @@ ss_tunnel_SOURCES = utils.c \
encrypt.c \
udprelay.c \
cache.c \
netutils.c \
tunnel.c
ss_server_SOURCES = utils.c \
@ -68,8 +70,10 @@ ss_redir_SOURCES = utils.c \
jconf.c \
json.c \
encrypt.c \
netutils.c \
redir.c
ss_redir_LDADD = $(SS_COMMON_LIBS)
ss_redir_LDADD += $(top_builddir)/libudns/libudns.la
endif
lib_LTLIBRARIES = libshadowsocks.la

73
src/Makefile.in

@ -115,13 +115,13 @@ am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) \
$(top_builddir)/libudns/libudns.la
libshadowsocks_la_DEPENDENCIES = $(am__DEPENDENCIES_3)
am__libshadowsocks_la_SOURCES_DIST = utils.c jconf.c json.c encrypt.c \
udprelay.c cache.c acl.c local.c win32.c
udprelay.c cache.c acl.c netutils.c local.c win32.c
@BUILD_WINCOMPAT_TRUE@am__objects_1 = libshadowsocks_la-win32.lo
am__objects_2 = libshadowsocks_la-utils.lo libshadowsocks_la-jconf.lo \
libshadowsocks_la-json.lo libshadowsocks_la-encrypt.lo \
libshadowsocks_la-udprelay.lo libshadowsocks_la-cache.lo \
libshadowsocks_la-acl.lo libshadowsocks_la-local.lo \
$(am__objects_1)
libshadowsocks_la-acl.lo libshadowsocks_la-netutils.lo \
libshadowsocks_la-local.lo $(am__objects_1)
am_libshadowsocks_la_OBJECTS = $(am__objects_2)
libshadowsocks_la_OBJECTS = $(am_libshadowsocks_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@ -135,25 +135,29 @@ libshadowsocks_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 local.c win32.c
udprelay.c cache.c acl.c netutils.c local.c win32.c
@BUILD_WINCOMPAT_TRUE@am__objects_3 = 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-local.$(OBJEXT) $(am__objects_3)
ss_local-netutils.$(OBJEXT) ss_local-local.$(OBJEXT) \
$(am__objects_3)
ss_local_OBJECTS = $(am_ss_local_OBJECTS)
ss_local_DEPENDENCIES = $(am__DEPENDENCIES_2) \
$(top_builddir)/libudns/libudns.la
ss_local_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(ss_local_CFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
am__ss_redir_SOURCES_DIST = utils.c jconf.c json.c encrypt.c redir.c
am__ss_redir_SOURCES_DIST = utils.c jconf.c json.c encrypt.c \
netutils.c redir.c
@BUILD_REDIRECTOR_TRUE@am_ss_redir_OBJECTS = utils.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ jconf.$(OBJEXT) json.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ encrypt.$(OBJEXT) redir.$(OBJEXT)
@BUILD_REDIRECTOR_TRUE@ encrypt.$(OBJEXT) netutils.$(OBJEXT) \
@BUILD_REDIRECTOR_TRUE@ redir.$(OBJEXT)
ss_redir_OBJECTS = $(am_ss_redir_OBJECTS)
@BUILD_REDIRECTOR_TRUE@ss_redir_DEPENDENCIES = $(am__DEPENDENCIES_2)
@BUILD_REDIRECTOR_TRUE@ss_redir_DEPENDENCIES = $(am__DEPENDENCIES_2) \
@BUILD_REDIRECTOR_TRUE@ $(top_builddir)/libudns/libudns.la
am_ss_server_OBJECTS = ss_server-utils.$(OBJEXT) \
ss_server-jconf.$(OBJEXT) ss_server-json.$(OBJEXT) \
ss_server-encrypt.$(OBJEXT) ss_server-udprelay.$(OBJEXT) \
@ -166,13 +170,13 @@ ss_server_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(ss_server_CFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
am__ss_tunnel_SOURCES_DIST = utils.c jconf.c json.c encrypt.c \
udprelay.c cache.c tunnel.c win32.c
udprelay.c cache.c netutils.c tunnel.c win32.c
@BUILD_WINCOMPAT_TRUE@am__objects_4 = 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-tunnel.$(OBJEXT) \
$(am__objects_4)
ss_tunnel-cache.$(OBJEXT) ss_tunnel-netutils.$(OBJEXT) \
ss_tunnel-tunnel.$(OBJEXT) $(am__objects_4)
ss_tunnel_OBJECTS = $(am_ss_tunnel_OBJECTS)
ss_tunnel_DEPENDENCIES = $(am__DEPENDENCIES_2) \
$(top_builddir)/libudns/libudns.la
@ -355,9 +359,9 @@ SS_COMMON_LIBS = $(top_builddir)/libev/libev.la \
$(INET_NTOP_LIB)
ss_local_SOURCES = utils.c jconf.c json.c encrypt.c udprelay.c cache.c \
acl.c local.c $(am__append_2)
acl.c netutils.c local.c $(am__append_2)
ss_tunnel_SOURCES = utils.c jconf.c json.c encrypt.c udprelay.c \
cache.c tunnel.c $(am__append_3)
cache.c netutils.c tunnel.c $(am__append_3)
ss_server_SOURCES = utils.c \
jconf.c \
json.c \
@ -377,9 +381,11 @@ ss_server_CFLAGS = $(AM_CFLAGS) -DUDPRELAY_REMOTE
@BUILD_REDIRECTOR_TRUE@ jconf.c \
@BUILD_REDIRECTOR_TRUE@ json.c \
@BUILD_REDIRECTOR_TRUE@ encrypt.c \
@BUILD_REDIRECTOR_TRUE@ netutils.c \
@BUILD_REDIRECTOR_TRUE@ redir.c
@BUILD_REDIRECTOR_TRUE@ss_redir_LDADD = $(SS_COMMON_LIBS)
@BUILD_REDIRECTOR_TRUE@ss_redir_LDADD = $(SS_COMMON_LIBS) \
@BUILD_REDIRECTOR_TRUE@ $(top_builddir)/libudns/libudns.la
lib_LTLIBRARIES = libshadowsocks.la
libshadowsocks_la_SOURCES = $(ss_local_SOURCES)
libshadowsocks_la_CFLAGS = $(ss_local_CFLAGS) -DLIB_ONLY
@ -528,9 +534,11 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_la-jconf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_la-json.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_la-local.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_la-netutils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_la-udprelay.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_la-utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshadowsocks_la-win32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/redir.Po@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@
@ -538,6 +546,7 @@ distclean-compile:
@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-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@
@ -553,6 +562,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-encrypt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-jconf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-json.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-netutils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-tunnel.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-udprelay.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ss_tunnel-utils.Po@am__quote@
@ -632,6 +642,13 @@ libshadowsocks_la-acl.lo: acl.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_la_CFLAGS) $(CFLAGS) -c -o libshadowsocks_la-acl.lo `test -f 'acl.c' || echo '$(srcdir)/'`acl.c
libshadowsocks_la-netutils.lo: netutils.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_la_CFLAGS) $(CFLAGS) -MT libshadowsocks_la-netutils.lo -MD -MP -MF $(DEPDIR)/libshadowsocks_la-netutils.Tpo -c -o libshadowsocks_la-netutils.lo `test -f 'netutils.c' || echo '$(srcdir)/'`netutils.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libshadowsocks_la-netutils.Tpo $(DEPDIR)/libshadowsocks_la-netutils.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netutils.c' object='libshadowsocks_la-netutils.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_la_CFLAGS) $(CFLAGS) -c -o libshadowsocks_la-netutils.lo `test -f 'netutils.c' || echo '$(srcdir)/'`netutils.c
libshadowsocks_la-local.lo: local.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_la_CFLAGS) $(CFLAGS) -MT libshadowsocks_la-local.lo -MD -MP -MF $(DEPDIR)/libshadowsocks_la-local.Tpo -c -o libshadowsocks_la-local.lo `test -f 'local.c' || echo '$(srcdir)/'`local.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libshadowsocks_la-local.Tpo $(DEPDIR)/libshadowsocks_la-local.Plo
@ -744,6 +761,20 @@ ss_local-acl.obj: acl.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-acl.obj `if test -f 'acl.c'; then $(CYGPATH_W) 'acl.c'; else $(CYGPATH_W) '$(srcdir)/acl.c'; fi`
ss_local-netutils.o: netutils.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-netutils.o -MD -MP -MF $(DEPDIR)/ss_local-netutils.Tpo -c -o ss_local-netutils.o `test -f 'netutils.c' || echo '$(srcdir)/'`netutils.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-netutils.Tpo $(DEPDIR)/ss_local-netutils.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netutils.c' object='ss_local-netutils.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-netutils.o `test -f 'netutils.c' || echo '$(srcdir)/'`netutils.c
ss_local-netutils.obj: netutils.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-netutils.obj -MD -MP -MF $(DEPDIR)/ss_local-netutils.Tpo -c -o ss_local-netutils.obj `if test -f 'netutils.c'; then $(CYGPATH_W) 'netutils.c'; else $(CYGPATH_W) '$(srcdir)/netutils.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-netutils.Tpo $(DEPDIR)/ss_local-netutils.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netutils.c' object='ss_local-netutils.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-netutils.obj `if test -f 'netutils.c'; then $(CYGPATH_W) 'netutils.c'; else $(CYGPATH_W) '$(srcdir)/netutils.c'; fi`
ss_local-local.o: local.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_local_CFLAGS) $(CFLAGS) -MT ss_local-local.o -MD -MP -MF $(DEPDIR)/ss_local-local.Tpo -c -o ss_local-local.o `test -f 'local.c' || echo '$(srcdir)/'`local.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_local-local.Tpo $(DEPDIR)/ss_local-local.Po
@ -968,6 +999,20 @@ ss_tunnel-cache.obj: cache.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_tunnel_CFLAGS) $(CFLAGS) -c -o ss_tunnel-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi`
ss_tunnel-netutils.o: netutils.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -MT ss_tunnel-netutils.o -MD -MP -MF $(DEPDIR)/ss_tunnel-netutils.Tpo -c -o ss_tunnel-netutils.o `test -f 'netutils.c' || echo '$(srcdir)/'`netutils.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_tunnel-netutils.Tpo $(DEPDIR)/ss_tunnel-netutils.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netutils.c' object='ss_tunnel-netutils.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_tunnel_CFLAGS) $(CFLAGS) -c -o ss_tunnel-netutils.o `test -f 'netutils.c' || echo '$(srcdir)/'`netutils.c
ss_tunnel-netutils.obj: netutils.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -MT ss_tunnel-netutils.obj -MD -MP -MF $(DEPDIR)/ss_tunnel-netutils.Tpo -c -o ss_tunnel-netutils.obj `if test -f 'netutils.c'; then $(CYGPATH_W) 'netutils.c'; else $(CYGPATH_W) '$(srcdir)/netutils.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_tunnel-netutils.Tpo $(DEPDIR)/ss_tunnel-netutils.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netutils.c' object='ss_tunnel-netutils.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_tunnel_CFLAGS) $(CFLAGS) -c -o ss_tunnel-netutils.obj `if test -f 'netutils.c'; then $(CYGPATH_W) 'netutils.c'; else $(CYGPATH_W) '$(srcdir)/netutils.c'; fi`
ss_tunnel-tunnel.o: tunnel.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ss_tunnel_CFLAGS) $(CFLAGS) -MT ss_tunnel-tunnel.o -MD -MP -MF $(DEPDIR)/ss_tunnel-tunnel.Tpo -c -o ss_tunnel-tunnel.o `test -f 'tunnel.c' || echo '$(srcdir)/'`tunnel.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ss_tunnel-tunnel.Tpo $(DEPDIR)/ss_tunnel-tunnel.Po

2
src/common.h

@ -39,7 +39,7 @@
int init_udprelay(const char *server_host, const char *server_port,
#ifdef UDPRELAY_LOCAL
const char *remote_host, const char *remote_port,
const struct sockaddr *remote_addr, const int remote_addr_len,
#ifdef UDPRELAY_TUNNEL
const ss_addr_t tunnel_addr,
#endif

120
src/local.c

@ -20,6 +20,10 @@
* <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
@ -39,10 +43,6 @@
#include <pthread.h>
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef LIB_ONLY
#include <pthread.h>
#include "shadowsocks.h"
@ -61,6 +61,7 @@
#include "win32.h"
#endif
#include "netutils.h"
#include "utils.h"
#include "local.h"
#include "socks5.h"
@ -96,8 +97,7 @@ static void accept_cb(EV_P_ ev_io *w, int revents);
static void signal_cb(EV_P_ ev_signal *w, int revents);
static int create_and_bind(const char *addr, const char *port);
static struct remote * connect_to_remote(struct listen_ctx *listener,
const char *host, const char *port);
static struct remote * connect_to_remote(struct listen_ctx *listener, struct sockaddr *addr);
static void free_remote(struct remote *remote);
static void close_and_free_remote(EV_P_ struct remote *remote);
static void free_server(struct server *server);
@ -254,8 +254,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
if (!fast_open || remote->direct) {
// connecting, wait until connected
connect(remote->fd, remote->addr_info->ai_addr,
remote->addr_info->ai_addrlen);
connect(remote->fd, (struct sockaddr *)&(remote->addr), remote->addr_len);
// wait on remote connected event
ev_io_stop(EV_A_ & server_recv_ctx->io);
@ -264,8 +263,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
} else {
#ifdef TCP_FASTOPEN
int s = sendto(remote->fd, remote->buf, r, MSG_FASTOPEN,
remote->addr_info->ai_addr,
remote->addr_info->ai_addrlen);
(struct sockaddr *)&(remote->addr), remote->addr_len);
if (s == -1) {
if (errno == EINPROGRESS) {
// in progress, wait until connected
@ -430,16 +428,18 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
LOGI("connect to %s:%s", host, port);
}
if ((acl && request->atyp == 1 && acl_contains_ip(host))
|| (acl && request->atyp == 3 &&
acl_contains_domain(host))) {
remote = connect_to_remote(server->listener, host, port);
remote->direct = 1;
if ((acl && request->atyp == 1 && acl_contains_ip(host))) {
if (verbose) {
LOGI("bypass %s:%s", host, port);
}
struct sockaddr_storage storage;
memset(&storage, 0, sizeof(struct sockaddr_storage));
if (get_sockaddr(host, port, &storage) != -1) {
remote = connect_to_remote(server->listener, (struct sockaddr *)&storage);
remote->direct = 1;
}
} else {
remote = connect_to_remote(server->listener, NULL, NULL);
remote = connect_to_remote(server->listener, NULL);
}
if (remote == NULL) {
@ -712,9 +712,6 @@ static void free_remote(struct remote *remote)
if (remote->buf != NULL) {
free(remote->buf);
}
if (remote->addr_info != NULL) {
freeaddrinfo(remote->addr_info);
}
free(remote->recv_ctx);
free(remote->send_ctx);
free(remote);
@ -798,40 +795,21 @@ static void close_and_free_server(EV_P_ struct server *server)
}
static struct remote * connect_to_remote(struct listen_ctx *listener,
const char *host, const char *port)
struct sockaddr *addr)
{
int sockfd;
struct addrinfo *remote_res;
struct sockaddr *remote_addr;
struct addrinfo hints;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
int index = rand() % listener->remote_num;
int err;
if (host == NULL || port == NULL) {
if (verbose) {
LOGI("connect to server: %s:%s", listener->remote_addr[index].host,
listener->remote_addr[index].port);
}
err = getaddrinfo(listener->remote_addr[index].host,
listener->remote_addr[index].port, &hints,
&remote_res);
if (addr == NULL) {
remote_addr = listener->remote_addr[index];
} else {
err = getaddrinfo(host, port, &hints, &remote_res);
}
if (err) {
ERROR("getaddrinfo");
return NULL;
remote_addr = addr;
}
sockfd = socket(remote_res->ai_family, remote_res->ai_socktype,
remote_res->ai_protocol);
int sockfd = socket(remote_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (sockfd < 0) {
ERROR("socket");
freeaddrinfo(remote_res);
return NULL;
}
@ -849,7 +827,8 @@ static struct remote * connect_to_remote(struct listen_ctx *listener,
#endif
struct remote *remote = new_remote(sockfd, listener->timeout);
remote->addr_info = remote_res;
remote->addr_len = get_sockaddr_len(remote_addr);
memcpy(&(remote->addr), remote_addr, remote->addr_len);
return remote;
}
@ -1084,13 +1063,17 @@ int main(int argc, char **argv)
// Setup proxy context
struct listen_ctx listen_ctx;
listen_ctx.remote_num = remote_num;
listen_ctx.remote_addr = malloc(sizeof(ss_addr_t) * remote_num);
while (remote_num > 0) {
int index = --remote_num;
if (remote_addr[index].port == NULL) {
remote_addr[index].port = remote_port;
listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *) * remote_num);
for (int i = 0; i < remote_num; i++) {
char *host = remote_addr[i].host;
char *port = remote_addr[i].port == NULL ? remote_port :
remote_addr[i].port;
struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage));
memset(storage, 0, sizeof(struct sockaddr_storage));
if (get_sockaddr(host, port, storage) == -1) {
FATAL("failed to resolve the provided hostname");
}
listen_ctx.remote_addr[index] = remote_addr[index];
listen_ctx.remote_addr[i] = (struct sockaddr *)storage;
}
listen_ctx.timeout = atoi(timeout);
listen_ctx.fd = listenfd;
@ -1098,17 +1081,14 @@ int main(int argc, char **argv)
listen_ctx.method = m;
struct ev_loop *loop = EV_DEFAULT;
if (!loop) {
FATAL("ev_loop error");
}
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
ev_io_start(loop, &listen_ctx.io);
// Setup UDP
if (udprelay) {
LOGI("udprelay enabled");
init_udprelay(local_addr, local_port, remote_addr[0].host,
remote_addr[0].port, m, listen_ctx.timeout, iface);
init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0],
get_sockaddr_len(listen_ctx.remote_addr[0]), m, listen_ctx.timeout, iface);
}
// setuid
@ -1131,6 +1111,9 @@ int main(int argc, char **argv)
free_udprelay();
ev_io_stop(loop, &listen_ctx.io);
for (int i = 0; i < remote_num; i++) {
free(listen_ctx.remote_addr[i]);
}
free(listen_ctx.remote_addr);
#ifdef __MINGW32__
@ -1142,6 +1125,7 @@ int main(int argc, char **argv)
return 0;
}
#else
int start_ss_local_server(profile_t profile)
@ -1199,10 +1183,12 @@ int start_ss_local_server(profile_t profile)
int listenfd;
listenfd = create_and_bind(local_addr, local_port_str);
if (listenfd < 0) {
FATAL("bind()");
ERROR("bind()");
return -1;
}
if (listen(listenfd, SOMAXCONN) == -1) {
FATAL("listen()");
ERROR("listen()");
return -1;
}
setnonblocking(listenfd);
LOGI("server listening at port %s", local_port_str);
@ -1211,26 +1197,28 @@ int start_ss_local_server(profile_t profile)
struct listen_ctx listen_ctx;
listen_ctx.remote_num = 1;
listen_ctx.remote_addr = malloc(sizeof(ss_addr_t));
listen_ctx.remote_addr[0].host = remote_host;
listen_ctx.remote_addr[0].port = remote_port_str;
listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *));
struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage));
memset(storage, 0, sizeof(struct sockaddr_storage));
if (get_sockaddr(remote_host, remote_port_str, storage) == -1) {
return -1;
}
listen_ctx.remote_addr[0] = (struct sockaddr *)storage;
listen_ctx.timeout = timeout;
listen_ctx.fd = listenfd;
listen_ctx.method = m;
listen_ctx.iface = NULL;
struct ev_loop *loop = EV_DEFAULT;
if (!loop) {
FATAL("ev_loop error");
}
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
ev_io_start(loop, &listen_ctx.io);
// Setup UDP
if (udprelay) {
LOGI("udprelay enabled");
init_udprelay(local_addr, local_port_str, remote_host, remote_port_str,
m, listen_ctx.timeout, NULL);
init_udprelay(local_addr, local_port_str, listen_ctx.remote_addr[0],
get_sockaddr_len(listen_ctx.remote_addr[0]), m,
listen_ctx.timeout, NULL);
}
// Init connections

6
src/local.h

@ -33,13 +33,12 @@
struct listen_ctx {
ev_io io;
ss_addr_t *remote_addr;
char *iface;
int remote_num;
int method;
int timeout;
int fd;
struct sockaddr sock;
struct sockaddr **remote_addr;
};
struct server_ctx {
@ -80,7 +79,8 @@ struct remote {
struct remote_ctx *recv_ctx;
struct remote_ctx *send_ctx;
struct server *server;
struct addrinfo *addr_info;
struct sockaddr_storage addr;
int addr_len;
};
#endif // _LOCAL_H

110
src/netutils.c

@ -0,0 +1,110 @@
/*
* netutils.c - Network utilities
*
* Copyright (C) 2013 - 2015, Max Lv <max.c.lv@gmail.com>
*
* This file is part of the shadowsocks-libev.
*
* shadowsocks-libev is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* shadowsocks-libev 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with shadowsocks-libev; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include <libcork/core.h>
#include <udns.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef __MINGW32__
#include "win32.h"
#else
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#endif
#include "netutils.h"
#include "utils.h"
int get_sockaddr_len(struct sockaddr *addr) {
if (addr->sa_family == AF_INET) {
return sizeof(struct sockaddr_in);
} else if (addr->sa_family == AF_INET6) {
return sizeof(struct sockaddr_in6);
}
return 0;
}
int get_sockaddr(char *host, char *port, struct sockaddr_storage *storage)
{
struct cork_ip ip;
if (cork_ip_init(&ip, host) != -1) {
if (ip.version == 4) {
struct sockaddr_in *addr = (struct sockaddr_in *)storage;
addr->sin_family = AF_INET;
dns_pton(AF_INET, host, &(addr->sin_addr));
if (port != NULL) {
addr->sin_port = htons(atoi(port));
}
} else if (ip.version == 6) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage;
addr->sin6_family = AF_INET6;
dns_pton(AF_INET, host, &(addr->sin6_addr));
if (port != NULL) {
addr->sin6_port = htons(atoi(port));
}
}
return 0;
} else {
struct addrinfo hints;
struct addrinfo *result, *rp;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */
hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */
int err = getaddrinfo(host, port, &hints, &result);
if (err != 0) {
LOGE("getaddrinfo: %s", gai_strerror(err));
return -1;
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
if (rp->ai_family == AF_INET) {
memcpy(storage, rp->ai_addr, sizeof(struct sockaddr_in));
break;
}
}
if (rp == NULL) {
for (rp = result; rp != NULL; rp = rp->ai_next) {
if (rp->ai_family == AF_INET6) {
memcpy(storage, rp->ai_addr, sizeof(struct sockaddr_in6));
break;
}
}
}
if (rp == NULL) {
LOGE("failed to resolve remote addr");
return -1;
}
freeaddrinfo(result);
return 0;
}
return -1;
}

24
src/netutils.h

@ -0,0 +1,24 @@
/*
* netutils.h - Network utilities
*
* Copyright (C) 2013 - 2015, Max Lv <max.c.lv@gmail.com>
*
* This file is part of the shadowsocks-libev.
*
* shadowsocks-libev is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* shadowsocks-libev 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with shadowsocks-libev; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/
int get_sockaddr_len(struct sockaddr *addr);
int get_sockaddr(char *host, char *port, struct sockaddr_storage *storage);

41
src/redir.c

@ -45,6 +45,7 @@
#include "config.h"
#endif
#include "netutils.h"
#include "utils.h"
#include "redir.h"
@ -562,24 +563,12 @@ static void accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(clientfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif
struct addrinfo hints, *res;
int sockfd;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
int index = rand() % listener->remote_num;
err =
getaddrinfo(listener->remote_addr[index].host,
listener->remote_addr[index].port, &hints, &res);
if (err) {
ERROR("getaddrinfo");
return;
}
struct sockaddr *remote_addr = listener->remote_addr[index];
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
int sockfd = socket(remote_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (sockfd < 0) {
ERROR("socket");
freeaddrinfo(res);
return;
}
@ -596,8 +585,7 @@ static void accept_cb(EV_P_ ev_io *w, int revents)
remote->server = server;
server->destaddr = destaddr;
connect(sockfd, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
connect(sockfd, remote_addr, get_sockaddr_len(remote_addr));
// listen to remote connected event
ev_io_start(EV_A_ & remote->send_ctx->io);
ev_timer_start(EV_A_ & remote->send_ctx->watcher);
@ -735,22 +723,23 @@ int main(int argc, char **argv)
// Setup proxy context
struct listen_ctx listen_ctx;
listen_ctx.remote_num = remote_num;
listen_ctx.remote_addr = malloc(sizeof(ss_addr_t) * remote_num);
while (remote_num > 0) {
int index = --remote_num;
if (remote_addr[index].port == NULL) {
remote_addr[index].port = remote_port;
listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *) * remote_num);
for (int i = 0; i < remote_num; i++) {
char *host = remote_addr[i].host;
char *port = remote_addr[i].port == NULL ? remote_port :
remote_addr[i].port;
struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage));
memset(storage, 0, sizeof(struct sockaddr_storage));
if (get_sockaddr(host, port, storage) == -1) {
FATAL("failed to resolve the provided hostname");
}
listen_ctx.remote_addr[index] = remote_addr[index];
listen_ctx.remote_addr[i] = (struct sockaddr *)storage;
}
listen_ctx.timeout = atoi(timeout);
listen_ctx.fd = listenfd;
listen_ctx.method = m;
struct ev_loop *loop = ev_default_loop(0);
if (!loop) {
FATAL("ev_loop error");
}
struct ev_loop *loop = EV_DEFAULT;
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
ev_io_start(loop, &listen_ctx.io);

3
src/redir.h

@ -29,12 +29,11 @@
struct listen_ctx {
ev_io io;
ss_addr_t *remote_addr;
int remote_num;
int timeout;
int fd;
int method;
struct sockaddr sock;
struct sockaddr **remote_addr;
};
struct server_ctx {

48
src/tunnel.c

@ -55,6 +55,7 @@
#include <libcork/core.h>
#include <udns.h>
#include "netutils.h"
#include "utils.h"
#include "tunnel.h"
@ -614,27 +615,12 @@ static void accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif
struct addrinfo hints, *res;
int sockfd;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
int index = rand() % listener->remote_num;
if (verbose) {
LOGI("connect to %s:%s", listener->remote_addr[index].host,
listener->remote_addr[index].port);
}
int err = getaddrinfo(listener->remote_addr[index].host,
listener->remote_addr[index].port, &hints, &res);
if (err) {
ERROR("getaddrinfo");
return;
}
struct sockaddr *remote_addr = listener->remote_addr[index];
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
int sockfd = socket(remote_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (sockfd < 0) {
ERROR("socket");
freeaddrinfo(res);
return;
}
@ -655,8 +641,7 @@ static void accept_cb(EV_P_ ev_io *w, int revents)
server->destaddr = listener->tunnel_addr;
server->remote = remote;
remote->server = server;
connect(sockfd, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
connect(sockfd, remote_addr, get_sockaddr_len(remote_addr));
// listen to remote connected event
ev_io_start(EV_A_ & remote->send_ctx->io);
ev_timer_start(EV_A_ & remote->send_ctx->watcher);
@ -822,31 +807,32 @@ int main(int argc, char **argv)
struct listen_ctx listen_ctx;
listen_ctx.tunnel_addr = tunnel_addr;
listen_ctx.remote_num = remote_num;
listen_ctx.remote_addr = malloc(sizeof(ss_addr_t) * remote_num);
while (remote_num > 0) {
int index = --remote_num;
if (remote_addr[index].port == NULL) {
remote_addr[index].port = remote_port;
listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *) * remote_num);
for (int i = 0; i < remote_num; i++) {
char *host = remote_addr[i].host;
char *port = remote_addr[i].port == NULL ? remote_port :
remote_addr[i].port;
struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage));
memset(storage, 0, sizeof(struct sockaddr_storage));
if (get_sockaddr(host, port, storage) == -1) {
FATAL("failed to resolve the provided hostname");
}
listen_ctx.remote_addr[index] = remote_addr[index];
listen_ctx.remote_addr[i] = (struct sockaddr *)storage;
}
listen_ctx.timeout = atoi(timeout);
listen_ctx.fd = listenfd;
listen_ctx.iface = iface;
listen_ctx.method = m;
struct ev_loop *loop = ev_default_loop(0);
if (!loop) {
FATAL("ev_loop error.");
}
struct ev_loop *loop = EV_DEFAULT;
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
ev_io_start(loop, &listen_ctx.io);
// Setup UDP
if (udprelay) {
LOGI("udprelay enabled");
init_udprelay(local_addr, local_port, remote_addr[0].host,
remote_addr[0].port,
init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0],
get_sockaddr_len(listen_ctx.remote_addr[0]),
tunnel_addr, m, listen_ctx.timeout, iface);
}

3
src/tunnel.h

@ -32,13 +32,12 @@
struct listen_ctx {
ev_io io;
ss_addr_t tunnel_addr;
ss_addr_t *remote_addr;
char *iface;
int remote_num;
int method;
int timeout;
int fd;
struct sockaddr sock;
struct sockaddr **remote_addr;
};
struct server_ctx {

36
src/udprelay.c

@ -789,26 +789,13 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
#endif
if (remote_ctx == NULL) {
struct addrinfo hints;
struct addrinfo *result;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */
hints.ai_socktype = SOCK_DGRAM; /* We want a UDP socket */
int s = getaddrinfo(server_ctx->remote_host, server_ctx->remote_port,
&hints, &result);
if (s != 0 || result == NULL) {
LOGE("[udp] getaddrinfo: %s", gai_strerror(s));
goto CLEAN_UP;
}
const struct sockaddr *remote_addr = server_ctx->remote_addr;
const int remote_addr_len = server_ctx->remote_addr_len;
// Bind to any port
int remotefd = create_remote_socket(result->ai_family == AF_INET6);
int remotefd = create_remote_socket(remote_addr->sa_family == AF_INET6);
if (remotefd < 0) {
ERROR("[udp] udprelay bind() error");
// remember to free addrinfo
freeaddrinfo(result);
goto CLEAN_UP;
}
setnonblocking(remotefd);
@ -825,13 +812,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
// Init remote_ctx
remote_ctx = new_remote(remotefd, server_ctx);
remote_ctx->src_addr = src_addr;
if (result->ai_addr->sa_family == AF_INET) {
memcpy(&(remote_ctx->dst_addr), result->ai_addr,
sizeof(struct sockaddr_in));
} else if (result->ai_addr->sa_family == AF_INET6) {
memcpy(&(remote_ctx->dst_addr), result->ai_addr,
sizeof(struct sockaddr_in6));
}
memcpy(&(remote_ctx->dst_addr), remote_addr, remote_addr_len);
remote_ctx->addr_header_len = addr_header_len;
memcpy(remote_ctx->addr_header, addr_header, addr_header_len);
@ -840,9 +821,6 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
// Start remote io
ev_io_start(EV_A_ & remote_ctx->io);
// clean up
freeaddrinfo(result);
}
if (offset > 0) {
@ -971,7 +949,7 @@ void free_cb(void *element)
int init_udprelay(const char *server_host, const char *server_port,
#ifdef UDPRELAY_LOCAL
const char *remote_host, const char *remote_port,
const struct sockaddr *remote_addr, const int remote_addr_len,
#ifdef UDPRELAY_TUNNEL
const ss_addr_t tunnel_addr,
#endif
@ -1004,8 +982,8 @@ int init_udprelay(const char *server_host, const char *server_port,
server_ctx->iface = iface;
server_ctx->conn_cache = conn_cache;
#ifdef UDPRELAY_LOCAL
server_ctx->remote_host = remote_host;
server_ctx->remote_port = remote_port;
server_ctx->remote_addr = remote_addr;
server_ctx->remote_addr_len = remote_addr_len;
#ifdef UDPRELAY_TUNNEL
server_ctx->tunnel_addr = tunnel_addr;
#endif

4
src/udprelay.h

@ -47,8 +47,8 @@ struct server_ctx {
const char *iface;
struct cache *conn_cache;
#ifdef UDPRELAY_LOCAL
const char *remote_host;
const char *remote_port;
const struct sockaddr *remote_addr;
int remote_addr_len;
#ifdef UDPRELAY_TUNNEL
ss_addr_t tunnel_addr;
#endif

4
src/utils.c

@ -31,12 +31,12 @@
#include <sys/types.h>
#include <sys/stat.h>
#include "utils.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "utils.h"
#ifdef HAVE_SETRLIMIT
#include <sys/time.h>
#include <sys/resource.h>

1
src/win32.c

@ -21,6 +21,7 @@
*/
#include "win32.h"
#include "utils.h"
#ifdef setsockopt
#undef setsockopt

1
src/win32.h

@ -31,7 +31,6 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include "utils.h"
#ifdef EWOULDBLOCK
#undef EWOULDBLOCK

Loading…
Cancel
Save