add unix socket
This commit is contained in:
@@ -15,7 +15,7 @@ rm -rf assets/armeabi-v7a
|
||||
rm -rf assets/x86
|
||||
mkdir -p assets/armeabi-v7a
|
||||
mkdir -p assets/x86
|
||||
for app in pdnsd redsocks ss-local ss-tunnel
|
||||
for app in pdnsd redsocks ss-local ss-tunnel tun2socks
|
||||
do
|
||||
try mv libs/armeabi-v7a/$app assets/armeabi-v7a/
|
||||
try mv libs/x86/$app assets/x86/
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:debuggable="true"
|
||||
android:name=".ShadowsocksApplication"
|
||||
android:hardwareAccelerated="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
|
||||
@@ -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_LITTLE_ENDIAN -DBADVPN_THREAD_SAFE
|
||||
LOCAL_CFLAGS += -DNDEBUG -DANDROID
|
||||
LOCAL_CFLAGS += -DTUN2SOCKS_JNI
|
||||
#LOCAL_CFLAGS += -DTUN2SOCKS_JNI
|
||||
|
||||
LOCAL_C_INCLUDES:= \
|
||||
$(LOCAL_PATH)/badvpn/lwip/src/include/ipv4 \
|
||||
@@ -284,13 +284,13 @@ TUN2SOCKS_SOURCES := \
|
||||
tun2socks/SocksUdpGwClient.c \
|
||||
udpgw_client/UdpGwClient.c
|
||||
|
||||
LOCAL_MODULE := tun2socks-jni
|
||||
LOCAL_MODULE := tun2socks
|
||||
|
||||
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_subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
#include <generated/blog_channel_tun2socks.h>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <sys/un.h>
|
||||
#include <structure/BAVL.h>
|
||||
BAVL connections_tree;
|
||||
typedef struct {
|
||||
@@ -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
|
||||
|
||||
#define LOGGER_STDOUT 1
|
||||
@@ -381,6 +470,72 @@ static void daemonize(const char* path) {
|
||||
close(STDOUT_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
|
||||
|
||||
int main (int argc, char **argv)
|
||||
@@ -436,8 +591,25 @@ int main (int argc, char **argv)
|
||||
BLog_SetChannelLoglevel(i, options.loglevel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
password_file_contents = NULL;
|
||||
@@ -563,12 +735,6 @@ int main (int argc, char **argv)
|
||||
// init number of clients
|
||||
num_clients = 0;
|
||||
|
||||
#if 0
|
||||
if (options.pid) {
|
||||
daemonize(options.pid);
|
||||
}
|
||||
#endif
|
||||
|
||||
// enter event loop
|
||||
BLog(BLOG_NOTICE, "entering event loop");
|
||||
BReactor_Exec(&ss);
|
||||
|
||||
@@ -123,7 +123,7 @@ object Shadowsocks {
|
||||
val FEATRUE_PREFS = Array(Key.route, Key.isGlobalProxy, Key.proxyedApps,
|
||||
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
|
||||
def updateListPreference(pref: Preference, value: String) {
|
||||
|
||||
@@ -45,7 +45,7 @@ import java.net.InetAddress
|
||||
import android.app._
|
||||
import android.content._
|
||||
import android.content.pm.{PackageInfo, PackageManager}
|
||||
import android.net.VpnService
|
||||
import android.net.{VpnService, LocalSocket, LocalSocketAddress}
|
||||
import android.os._
|
||||
import android.support.v4.app.NotificationCompat
|
||||
import android.util.Log
|
||||
@@ -322,19 +322,33 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
||||
|
||||
spawn {
|
||||
Tun2Socks.start(cmd.split(" "))
|
||||
}
|
||||
Console.runCommand(cmd)
|
||||
|
||||
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. */
|
||||
def handleConnection: Boolean = {
|
||||
startVpn()
|
||||
startShadowsocksDaemon()
|
||||
if (!config.isUdpDns) {
|
||||
startDnsDaemon()
|
||||
startDnsTunnel()
|
||||
}
|
||||
startVpn()
|
||||
true
|
||||
}
|
||||
|
||||
@@ -362,7 +376,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
}
|
||||
|
||||
def killProcesses() {
|
||||
for (task <- Array("ss-local", "ss-tunnel", "pdnsd")) {
|
||||
for (task <- Array("ss-local", "ss-tunnel", "pdnsd", "tun2socks")) {
|
||||
try {
|
||||
val pid = scala.io.Source.fromFile(Path.BASE + task + ".pid").mkString.trim.toInt
|
||||
Process.killProcess(pid)
|
||||
@@ -371,7 +385,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
case e: Throwable => Log.e(TAG, "unable to kill " + task, e)
|
||||
}
|
||||
}
|
||||
Tun2Socks.stop();
|
||||
}
|
||||
|
||||
override def startRunner(c: Config) {
|
||||
|
||||
Reference in New Issue
Block a user