Commit 9ee2345f authored by Max Lv's avatar Max Lv

add unix socket

parent 567543d0
...@@ -15,7 +15,7 @@ rm -rf assets/armeabi-v7a ...@@ -15,7 +15,7 @@ rm -rf assets/armeabi-v7a
rm -rf assets/x86 rm -rf assets/x86
mkdir -p assets/armeabi-v7a mkdir -p assets/armeabi-v7a
mkdir -p assets/x86 mkdir -p assets/x86
for app in pdnsd redsocks ss-local ss-tunnel for app in pdnsd redsocks ss-local ss-tunnel tun2socks
do do
try mv libs/armeabi-v7a/$app assets/armeabi-v7a/ try mv libs/armeabi-v7a/$app assets/armeabi-v7a/
try mv libs/x86/$app assets/x86/ try mv libs/x86/$app assets/x86/
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
<application <application
android:allowBackup="true" android:allowBackup="true"
android:debuggable="true"
android:name=".ShadowsocksApplication" android:name=".ShadowsocksApplication"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
......
...@@ -214,7 +214,7 @@ LOCAL_CFLAGS += -DBADVPN_THREADWORK_USE_PTHREAD -DBADVPN_LINUX -DBADVPN_BREACTOR ...@@ -214,7 +214,7 @@ LOCAL_CFLAGS += -DBADVPN_THREADWORK_USE_PTHREAD -DBADVPN_LINUX -DBADVPN_BREACTOR
LOCAL_CFLAGS += -DBADVPN_USE_SELFPIPE -DBADVPN_USE_EPOLL LOCAL_CFLAGS += -DBADVPN_USE_SELFPIPE -DBADVPN_USE_EPOLL
LOCAL_CFLAGS += -DBADVPN_LITTLE_ENDIAN -DBADVPN_THREAD_SAFE LOCAL_CFLAGS += -DBADVPN_LITTLE_ENDIAN -DBADVPN_THREAD_SAFE
LOCAL_CFLAGS += -DNDEBUG -DANDROID LOCAL_CFLAGS += -DNDEBUG -DANDROID
LOCAL_CFLAGS += -DTUN2SOCKS_JNI #LOCAL_CFLAGS += -DTUN2SOCKS_JNI
LOCAL_C_INCLUDES:= \ LOCAL_C_INCLUDES:= \
$(LOCAL_PATH)/badvpn/lwip/src/include/ipv4 \ $(LOCAL_PATH)/badvpn/lwip/src/include/ipv4 \
...@@ -284,13 +284,13 @@ TUN2SOCKS_SOURCES := \ ...@@ -284,13 +284,13 @@ TUN2SOCKS_SOURCES := \
tun2socks/SocksUdpGwClient.c \ tun2socks/SocksUdpGwClient.c \
udpgw_client/UdpGwClient.c udpgw_client/UdpGwClient.c
LOCAL_MODULE := tun2socks-jni LOCAL_MODULE := tun2socks
LOCAL_LDLIBS := -ldl -llog LOCAL_LDLIBS := -ldl -llog
LOCAL_SRC_FILES := $(addprefix badvpn/, $(TUN2SOCKS_SOURCES)) tun2socks-jni.cpp LOCAL_SRC_FILES := $(addprefix badvpn/, $(TUN2SOCKS_SOURCES))
include $(BUILD_SHARED_LIBRARY) include $(BUILD_EXECUTABLE)
# OpenSSL # OpenSSL
openssl_subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \ openssl_subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#include <generated/blog_channel_tun2socks.h> #include <generated/blog_channel_tun2socks.h>
#ifdef ANDROID #ifdef ANDROID
#include <sys/un.h>
#include <structure/BAVL.h> #include <structure/BAVL.h>
BAVL connections_tree; BAVL connections_tree;
typedef struct { typedef struct {
...@@ -145,6 +146,94 @@ static void tcp_remove(struct tcp_pcb* pcb_list) ...@@ -145,6 +146,94 @@ static void tcp_remove(struct tcp_pcb* pcb_list)
} }
} }
ssize_t
sock_fd_write(int sock, void *buf, ssize_t buflen, int fd)
{
ssize_t size;
struct msghdr msg;
struct iovec iov;
union {
struct cmsghdr cmsghdr;
char control[CMSG_SPACE(sizeof (int))];
} cmsgu;
struct cmsghdr *cmsg;
iov.iov_base = buf;
iov.iov_len = buflen;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
if (fd != -1) {
msg.msg_control = cmsgu.control;
msg.msg_controllen = sizeof(cmsgu.control);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof (int));
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
*((int *) CMSG_DATA(cmsg)) = fd;
} else {
msg.msg_control = NULL;
msg.msg_controllen = 0;
}
size = sendmsg(sock, &msg, 0);
if (size < 0)
perror ("sendmsg");
return size;
}
ssize_t
sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd)
{
ssize_t size;
if (fd) {
struct msghdr msg;
struct iovec iov;
union {
struct cmsghdr cmsghdr;
char control[CMSG_SPACE(sizeof (int))];
} cmsgu;
struct cmsghdr *cmsg;
iov.iov_base = buf;
iov.iov_len = bufsize;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgu.control;
msg.msg_controllen = sizeof(cmsgu.control);
size = recvmsg (sock, &msg, 0);
if (size < 0) {
perror ("recvmsg");
return -1;
}
cmsg = CMSG_FIRSTHDR(&msg);
if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmsg->cmsg_level != SOL_SOCKET) {
return -1;
}
if (cmsg->cmsg_type != SCM_RIGHTS) {
return -1;
}
*fd = *((int *) CMSG_DATA(cmsg));
} else {
*fd = -1;
return -1;
}
}
return size;
}
#endif #endif
#define LOGGER_STDOUT 1 #define LOGGER_STDOUT 1
...@@ -381,6 +470,72 @@ static void daemonize(const char* path) { ...@@ -381,6 +470,72 @@ static void daemonize(const char* path) {
close(STDOUT_FILENO); close(STDOUT_FILENO);
close(STDERR_FILENO); close(STDERR_FILENO);
} }
int
recv_tun_fd (void)
{
int s_fd, c_fd, fd_to_read;
struct sockaddr_un addr;
socklen_t addr_len;
char buf[16];
s_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (s_fd < 0) {
BLog(BLOG_ERROR, "Error to create local socket");
return -1;
}
BLog(BLOG_NOTICE, "Create socket");
addr_len = sizeof(struct sockaddr_un);
memset(&addr, 0, addr_len);
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path + 1, 14, "tun2socks");
if (bind(s_fd, (struct sockaddr *) &addr, addr_len) != 0)
{
BLog(BLOG_ERROR, "Error to bind local socket");
close(s_fd);
return -1;
}
BLog(BLOG_NOTICE, "Bind socket");
if (listen(s_fd, 5) != 0)
{
BLog(BLOG_ERROR, "Error to listen on local socket");
close(s_fd);
return -1;
}
BLog(BLOG_NOTICE, "Listen on socket");
if ((c_fd = accept(s_fd, (struct sockaddr *)&addr, &addr_len)) != -1)
{
char buf[1];
BLog(BLOG_NOTICE, "Accept a connection");
read(c_fd, buf, 1);
sock_fd_read(c_fd, buf, sizeof(buf), &fd_to_read);
buf[0] = 0;
write(c_fd, buf, 1);
close(c_fd);
}
else
{
BLog(BLOG_ERROR, "Error to accept socket");
close(s_fd);
return -1;
}
close(s_fd);
if (fd_to_read == 0) return -1;
options.tun_fd = fd_to_read;
}
#endif #endif
int main (int argc, char **argv) int main (int argc, char **argv)
...@@ -436,8 +591,25 @@ int main (int argc, char **argv) ...@@ -436,8 +591,25 @@ int main (int argc, char **argv)
BLog_SetChannelLoglevel(i, options.loglevel); BLog_SetChannelLoglevel(i, options.loglevel);
} }
} }
BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION); BLog(BLOG_NOTICE, "initializing "GLOBAL_PRODUCT_NAME" "PROGRAM_NAME" "GLOBAL_VERSION);
#ifdef ANDROID
if (options.pid) {
daemonize(options.pid);
}
BLog(BLOG_NOTICE, "Receiving the tun fd");
// Wait to recevie tun fd
if (recv_tun_fd() == -1) {
BLog(BLOG_ERROR, "Failed to recv tun fd");
return -1;
}
BLog(BLOG_NOTICE, "Received the tun fd successfully");
#endif
// clear password contents pointer // clear password contents pointer
password_file_contents = NULL; password_file_contents = NULL;
...@@ -563,12 +735,6 @@ int main (int argc, char **argv) ...@@ -563,12 +735,6 @@ int main (int argc, char **argv)
// init number of clients // init number of clients
num_clients = 0; num_clients = 0;
#if 0
if (options.pid) {
daemonize(options.pid);
}
#endif
// enter event loop // enter event loop
BLog(BLOG_NOTICE, "entering event loop"); BLog(BLOG_NOTICE, "entering event loop");
BReactor_Exec(&ss); BReactor_Exec(&ss);
......
...@@ -123,7 +123,7 @@ object Shadowsocks { ...@@ -123,7 +123,7 @@ object Shadowsocks {
val FEATRUE_PREFS = Array(Key.route, Key.isGlobalProxy, Key.proxyedApps, val FEATRUE_PREFS = Array(Key.route, Key.isGlobalProxy, Key.proxyedApps,
Key.isUdpDns, Key.isAutoConnect) Key.isUdpDns, Key.isAutoConnect)
val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL) val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL, Executable.TUN2SOCKS)
// Helper functions // Helper functions
def updateListPreference(pref: Preference, value: String) { def updateListPreference(pref: Preference, value: String) {
......
...@@ -45,7 +45,7 @@ import java.net.InetAddress ...@@ -45,7 +45,7 @@ import java.net.InetAddress
import android.app._ import android.app._
import android.content._ import android.content._
import android.content.pm.{PackageInfo, PackageManager} import android.content.pm.{PackageInfo, PackageManager}
import android.net.VpnService import android.net.{VpnService, LocalSocket, LocalSocketAddress}
import android.os._ import android.os._
import android.support.v4.app.NotificationCompat import android.support.v4.app.NotificationCompat
import android.util.Log import android.util.Log
...@@ -322,19 +322,33 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -322,19 +322,33 @@ class ShadowsocksVpnService extends VpnService with BaseService {
if (BuildConfig.DEBUG) Log.d(TAG, cmd) if (BuildConfig.DEBUG) Log.d(TAG, cmd)
spawn { Console.runCommand(cmd)
Tun2Socks.start(cmd.split(" "))
} Thread.sleep(300)
// try {
val localSocket = new LocalSocket()
localSocket.setFileDescriptorsForSend(Array(conn.getFileDescriptor))
val localAddr = new LocalSocketAddress("tun2socks")
localSocket.connect(localAddr)
val output = localSocket.getOutputStream
output.write(1)
output.flush()
output.close()
localSocket.close()
// } catch {
// case ex: Exception => // Ignored
// }
} }
/** Called when the activity is first created. */ /** Called when the activity is first created. */
def handleConnection: Boolean = { def handleConnection: Boolean = {
startVpn()
startShadowsocksDaemon() startShadowsocksDaemon()
if (!config.isUdpDns) { if (!config.isUdpDns) {
startDnsDaemon() startDnsDaemon()
startDnsTunnel() startDnsTunnel()
} }
startVpn()
true true
} }
...@@ -362,7 +376,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -362,7 +376,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
} }
def killProcesses() { def killProcesses() {
for (task <- Array("ss-local", "ss-tunnel", "pdnsd")) { for (task <- Array("ss-local", "ss-tunnel", "pdnsd", "tun2socks")) {
try { try {
val pid = scala.io.Source.fromFile(Path.BASE + task + ".pid").mkString.trim.toInt val pid = scala.io.Source.fromFile(Path.BASE + task + ".pid").mkString.trim.toInt
Process.killProcess(pid) Process.killProcess(pid)
...@@ -371,7 +385,6 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -371,7 +385,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
case e: Throwable => Log.e(TAG, "unable to kill " + task, e) case e: Throwable => Log.e(TAG, "unable to kill " + task, e)
} }
} }
Tun2Socks.stop();
} }
override def startRunner(c: Config) { override def startRunner(c: Config) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment