Commit 90b75009 authored by Max Lv's avatar Max Lv

Apply udpgw patch from linusyang

parent eb046e49
......@@ -39,6 +39,16 @@
#define UDPGW_CLIENT_FLAG_DNS (1 << 2)
#define UDPGW_CLIENT_FLAG_IPV6 (1 << 3)
#ifdef BADVPN_SOCKS_UDP_RELAY
B_START_PACKED
struct socks_udp_header {
uint16_t rsv;
uint8_t frag;
uint8_t atyp;
} B_PACKED;
B_END_PACKED
#endif
B_START_PACKED
struct udpgw_header {
uint8_t flags;
......@@ -63,7 +73,11 @@ B_END_PACKED
static int udpgw_compute_mtu (int dgram_mtu)
{
bsize_t bs = bsize_add(
#ifdef BADVPN_SOCKS_UDP_RELAY
bsize_fromsize(sizeof(struct socks_udp_header)),
#else
bsize_fromsize(sizeof(struct udpgw_header)),
#endif
bsize_add(
bsize_max(
bsize_fromsize(sizeof(struct udpgw_addr_ipv4)),
......
......@@ -33,6 +33,13 @@
#include <generated/blog_channel_SocksUdpGwClient.h>
#ifdef BADVPN_SOCKS_UDP_RELAY
#include <misc/socks_proto.h>
#define CONNECTION_UDP_BUFFER_SIZE 1
#else
static void free_socks (SocksUdpGwClient *o);
static void try_connect (SocksUdpGwClient *o);
static void reconnect_timer_handler (SocksUdpGwClient *o);
......@@ -40,6 +47,317 @@ static void socks_client_handler (SocksUdpGwClient *o, int event);
static void udpgw_handler_servererror (SocksUdpGwClient *o);
static void udpgw_handler_received (SocksUdpGwClient *o, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len);
#endif
#ifdef BADVPN_SOCKS_UDP_RELAY
static void dgram_handler (SocksUdpGwClient_connection *o, int event);
static void dgram_handler_received (SocksUdpGwClient_connection *o, uint8_t *data, int data_len);
static int conaddr_comparator (void *unused, SocksUdpGwClient_conaddr *v1, SocksUdpGwClient_conaddr *v2);
static SocksUdpGwClient_connection * find_connection (SocksUdpGwClient *o, SocksUdpGwClient_conaddr conaddr);
static SocksUdpGwClient_connection * reuse_connection (SocksUdpGwClient *o, SocksUdpGwClient_conaddr conaddr);
static void connection_send (SocksUdpGwClient_connection *o, const uint8_t *data, int data_len);
static void connection_first_job_handler (SocksUdpGwClient_connection *con);
static SocksUdpGwClient_connection *connection_init (SocksUdpGwClient *client, SocksUdpGwClient_conaddr conaddr, const uint8_t *data, int data_len);
static void connection_free (SocksUdpGwClient_connection *o);
static void dgram_handler (SocksUdpGwClient_connection *o, int event)
{
SocksUdpGwClient *client = o->client;
ASSERT(client);
DebugObject_Access(&client->d_obj);
BLog(BLOG_INFO, "UDP error");
}
static void dgram_handler_received (SocksUdpGwClient_connection *o, uint8_t *data, int data_len)
{
SocksUdpGwClient *client = o->client;
ASSERT(client);
DebugObject_Access(&client->d_obj);
ASSERT(data_len >= 0)
ASSERT(data_len <= client->udpgw_mtu)
// accept packet
PacketPassInterface_Done(&o->udp_recv_if);
// check header
if (data_len < sizeof(struct socks_udp_header)) {
BLog(BLOG_ERROR, "missing header");
return;
}
struct socks_udp_header header;
memcpy(&header, data, sizeof(header));
data += sizeof(header);
data_len -= sizeof(header);
uint8_t frag = header.frag;
uint8_t atyp = header.atyp;
// check fragment
if (frag) {
BLog(BLOG_ERROR, "unexpected frag");
return;
}
// parse address
BAddr remote_addr;
if (atyp == SOCKS_ATYP_IPV6) {
if (data_len < sizeof(struct udpgw_addr_ipv6)) {
BLog(BLOG_ERROR, "missing ipv6 address");
return;
}
struct udpgw_addr_ipv6 addr_ipv6;
memcpy(&addr_ipv6, data, sizeof(addr_ipv6));
data += sizeof(addr_ipv6);
data_len -= sizeof(addr_ipv6);
BAddr_InitIPv6(&remote_addr, addr_ipv6.addr_ip, addr_ipv6.addr_port);
} else {
if (data_len < sizeof(struct udpgw_addr_ipv4)) {
BLog(BLOG_ERROR, "missing ipv4 address");
return;
}
struct udpgw_addr_ipv4 addr_ipv4;
memcpy(&addr_ipv4, data, sizeof(addr_ipv4));
data += sizeof(addr_ipv4);
data_len -= sizeof(addr_ipv4);
BAddr_InitIPv4(&remote_addr, addr_ipv4.addr_ip, addr_ipv4.addr_port);
}
// check remote addr
if (!BAddr_Compare(&remote_addr, &o->conaddr.remote_addr)) {
BLog(BLOG_ERROR, "remote addr not match");
return;
}
// check remaining data
if (data_len > client->udp_mtu) {
BLog(BLOG_ERROR, "too much data");
return;
}
// submit to user
client->handler_received(client->user, o->conaddr.local_addr, remote_addr, data, data_len);
}
static int conaddr_comparator (void *unused, SocksUdpGwClient_conaddr *v1, SocksUdpGwClient_conaddr *v2)
{
int r = BAddr_CompareOrder(&v1->remote_addr, &v2->remote_addr);
if (r) {
return r;
}
return BAddr_CompareOrder(&v1->local_addr, &v2->local_addr);
}
static SocksUdpGwClient_connection * find_connection (SocksUdpGwClient *o, SocksUdpGwClient_conaddr conaddr)
{
BAVLNode *tree_node = BAVL_LookupExact(&o->connections_tree, &conaddr);
if (!tree_node) {
return NULL;
}
return UPPER_OBJECT(tree_node, SocksUdpGwClient_connection, connections_tree_node);
}
static SocksUdpGwClient_connection * reuse_connection (SocksUdpGwClient *o, SocksUdpGwClient_conaddr conaddr)
{
ASSERT(!find_connection(o, conaddr))
ASSERT(o->num_connections > 0)
// get least recently used connection
SocksUdpGwClient_connection *con = UPPER_OBJECT(LinkedList1_GetFirst(&o->connections_list), SocksUdpGwClient_connection, connections_list_node);
// remove from connections tree by conaddr
BAVL_Remove(&o->connections_tree, &con->connections_tree_node);
// set new conaddr
con->conaddr = conaddr;
// insert to connections tree by conaddr
ASSERT_EXECUTE(BAVL_Insert(&o->connections_tree, &con->connections_tree_node, NULL))
return con;
}
static void connection_send (SocksUdpGwClient_connection *o, const uint8_t *data, int data_len)
{
// get buffer location
uint8_t *out;
if (!BufferWriter_StartPacket(&o->udp_send_writer, &out)) {
BLog(BLOG_ERROR, "out of UDP buffer");
return;
}
int out_pos = 0;
// write header
BAddr remote_addr = o->conaddr.remote_addr;
struct socks_udp_header header;
header.rsv = 0;
header.frag = 0;
if (remote_addr.type == BADDR_TYPE_IPV4) {
header.atyp = SOCKS_ATYP_IPV4;
} else {
header.atyp = SOCKS_ATYP_IPV6;
}
memcpy(out + out_pos, &header, sizeof(header));
out_pos += sizeof(header);
// write address
switch (remote_addr.type) {
case BADDR_TYPE_IPV4: {
struct udpgw_addr_ipv4 addr_ipv4;
addr_ipv4.addr_ip = remote_addr.ipv4.ip;
addr_ipv4.addr_port = remote_addr.ipv4.port;
memcpy(out + out_pos, &addr_ipv4, sizeof(addr_ipv4));
out_pos += sizeof(addr_ipv4);
} break;
case BADDR_TYPE_IPV6: {
struct udpgw_addr_ipv6 addr_ipv6;
memcpy(addr_ipv6.addr_ip, remote_addr.ipv6.ip, sizeof(addr_ipv6.addr_ip));
addr_ipv6.addr_port = remote_addr.ipv6.port;
memcpy(out + out_pos, &addr_ipv6, sizeof(addr_ipv6));
out_pos += sizeof(addr_ipv6);
} break;
}
// write packet to buffer
memcpy(out + out_pos, data, data_len);
out_pos += data_len;
// submit written message
BufferWriter_EndPacket(&o->udp_send_writer, out_pos);
}
static void connection_first_job_handler (SocksUdpGwClient_connection *con)
{
connection_send(con, con->first_data, con->first_data_len);
}
static SocksUdpGwClient_connection *connection_init (SocksUdpGwClient *client, SocksUdpGwClient_conaddr conaddr, const uint8_t *data, int data_len)
{
// allocate structure
SocksUdpGwClient_connection *o = (SocksUdpGwClient_connection *) malloc(sizeof(*o));
if (!o) {
BLog(BLOG_ERROR, "malloc failed");
goto fail;
}
// init arguments
o->client = client;
o->conaddr = conaddr;
o->first_data = data;
o->first_data_len = data_len;
// init first job
BPending_Init(&o->first_job, BReactor_PendingGroup(client->reactor), (BPending_handler)connection_first_job_handler, o);
BPending_Set(&o->first_job);
// init UDP dgram
if (!BDatagram_Init(&o->udp_dgram, client->socks_server_addr.type, client->reactor, o, (BDatagram_handler)dgram_handler)) {
goto fail0;
}
// set SO_REUSEADDR
if (!BDatagram_SetReuseAddr(&o->udp_dgram, 1)) {
BLog(BLOG_ERROR, "set SO_REUSEADDR failed");
goto fail1;
}
// set UDP dgram send address
BIPAddr ipaddr;
memset(&ipaddr, 0, sizeof(ipaddr));
ipaddr.type = client->socks_server_addr.type;
BDatagram_SetSendAddrs(&o->udp_dgram, client->socks_server_addr, ipaddr);
// init UDP dgram interfaces
BDatagram_SendAsync_Init(&o->udp_dgram, client->udp_mtu);
BDatagram_RecvAsync_Init(&o->udp_dgram, client->udp_mtu);
// init UDP writer
BufferWriter_Init(&o->udp_send_writer, client->udp_mtu, BReactor_PendingGroup(client->reactor));
// init UDP buffer
if (!PacketBuffer_Init(&o->udp_send_buffer, BufferWriter_GetOutput(&o->udp_send_writer), BDatagram_SendAsync_GetIf(&o->udp_dgram), CONNECTION_UDP_BUFFER_SIZE, BReactor_PendingGroup(client->reactor))) {
BLog(BLOG_ERROR, "PacketBuffer_Init failed");
goto fail2;
}
// init UDP recv interface
PacketPassInterface_Init(&o->udp_recv_if, client->udp_mtu, (PacketPassInterface_handler_send)dgram_handler_received, o, BReactor_PendingGroup(client->reactor));
// init UDP recv buffer
if (!SinglePacketBuffer_Init(&o->udp_recv_buffer, BDatagram_RecvAsync_GetIf(&o->udp_dgram), &o->udp_recv_if, BReactor_PendingGroup(client->reactor))) {
BLog(BLOG_ERROR, "SinglePacketBuffer_Init failed");
goto fail3;
}
// insert to connections tree by conaddr
ASSERT_EXECUTE(BAVL_Insert(&client->connections_tree, &o->connections_tree_node, NULL));
// insert to connections list
LinkedList1_Append(&client->connections_list, &o->connections_list_node);
// increment number of connections
client->num_connections++;
// succeed to init
return o;
fail3:
PacketPassInterface_Free(&o->udp_recv_if);
PacketBuffer_Free(&o->udp_send_buffer);
fail2:
BufferWriter_Free(&o->udp_send_writer);
BDatagram_RecvAsync_Free(&o->udp_dgram);
BDatagram_SendAsync_Free(&o->udp_dgram);
fail1:
BDatagram_Free(&o->udp_dgram);
fail0:
BPending_Free(&o->first_job);
free(o);
fail:
return NULL;
}
static void connection_free (SocksUdpGwClient_connection *o)
{
SocksUdpGwClient *client = o->client;
// decrement number of connections
client->num_connections--;
// remove from connections list
LinkedList1_Remove(&client->connections_list, &o->connections_list_node);
// remove from connections tree by conaddr
BAVL_Remove(&client->connections_tree, &o->connections_tree_node);
// free UDP receive buffer
SinglePacketBuffer_Free(&o->udp_recv_buffer);
// free UDP receive interface
PacketPassInterface_Free(&o->udp_recv_if);
// free UDP buffer
PacketBuffer_Free(&o->udp_send_buffer);
// free UDP writer
BufferWriter_Free(&o->udp_send_writer);
// free UDP dgram interfaces
BDatagram_RecvAsync_Free(&o->udp_dgram);
BDatagram_SendAsync_Free(&o->udp_dgram);
// free UDP dgram
BDatagram_Free(&o->udp_dgram);
// free structure
free(o);
}
#else
static void free_socks (SocksUdpGwClient *o)
{
ASSERT(o->have_socks)
......@@ -158,6 +476,8 @@ static void udpgw_handler_received (SocksUdpGwClient *o, BAddr local_addr, BAddr
return;
}
#endif
int SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time,
BAddr socks_server_addr, const struct BSocksClient_auth_info *auth_info, size_t num_auth_info,
BAddr remote_udpgw_addr, btime_t reconnect_time, BReactor *reactor, void *user,
......@@ -165,7 +485,9 @@ int SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections
{
// see asserts in UdpGwClient_Init
ASSERT(!BAddr_IsInvalid(&socks_server_addr))
#ifndef BADVPN_SOCKS_UDP_RELAY
ASSERT(remote_udpgw_addr.type == BADDR_TYPE_IPV4 || remote_udpgw_addr.type == BADDR_TYPE_IPV6)
#endif
// init arguments
o->udp_mtu = udp_mtu;
......@@ -177,6 +499,22 @@ int SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections
o->user = user;
o->handler_received = handler_received;
#ifdef BADVPN_SOCKS_UDP_RELAY
// compute MTUs
o->udpgw_mtu = udpgw_compute_mtu(o->udp_mtu);
o->max_connections = max_connections;
// limit max connections to number of conid's
if (o->max_connections > UINT16_MAX + 1) {
o->max_connections = UINT16_MAX + 1;
}
// init connections tree by conaddr
BAVL_Init(&o->connections_tree, OFFSET_DIFF(SocksUdpGwClient_connection, conaddr, connections_tree_node), (BAVL_comparator)conaddr_comparator, NULL);
// init connections list
LinkedList1_Init(&o->connections_list);
#else
// init udpgw client
if (!UdpGwClient_Init(&o->udpgw_client, udp_mtu, max_connections, send_buffer_size, keepalive_time, o->reactor, o,
(UdpGwClient_handler_servererror)udpgw_handler_servererror,
......@@ -193,6 +531,7 @@ int SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections
// try connecting
try_connect(o);
#endif
DebugObject_Init(&o->d_obj);
return 1;
......@@ -205,6 +544,13 @@ void SocksUdpGwClient_Free (SocksUdpGwClient *o)
{
DebugObject_Free(&o->d_obj);
#ifdef BADVPN_SOCKS_UDP_RELAY
// free connections
while (!LinkedList1_IsEmpty(&o->connections_list)) {
SocksUdpGwClient_connection *con = UPPER_OBJECT(LinkedList1_GetFirst(&o->connections_list), SocksUdpGwClient_connection, connections_list_node);
connection_free(con);
}
#else
// free SOCKS
if (o->have_socks) {
free_socks(o);
......@@ -215,6 +561,7 @@ void SocksUdpGwClient_Free (SocksUdpGwClient *o)
// free udpgw client
UdpGwClient_Free(&o->udpgw_client);
#endif
}
void SocksUdpGwClient_SubmitPacket (SocksUdpGwClient *o, BAddr local_addr, BAddr remote_addr, int is_dns, const uint8_t *data, int data_len)
......@@ -222,7 +569,39 @@ void SocksUdpGwClient_SubmitPacket (SocksUdpGwClient *o, BAddr local_addr, BAddr
DebugObject_Access(&o->d_obj);
// see asserts in UdpGwClient_SubmitPacket
#ifdef BADVPN_SOCKS_UDP_RELAY
ASSERT(local_addr.type == BADDR_TYPE_IPV4 || local_addr.type == BADDR_TYPE_IPV6)
ASSERT(remote_addr.type == BADDR_TYPE_IPV4 || remote_addr.type == BADDR_TYPE_IPV6)
ASSERT(data_len >= 0)
ASSERT(data_len <= o->udp_mtu)
// build conaddr
SocksUdpGwClient_conaddr conaddr;
conaddr.local_addr = local_addr;
conaddr.remote_addr = remote_addr;
// lookup connection
SocksUdpGwClient_connection *con = find_connection(o, conaddr);
// if no connection and can't create a new one, reuse the least recently used une
if (!con && o->num_connections == o->max_connections) {
con = reuse_connection(o, conaddr);
}
if (!con) {
// create new connection
con = connection_init(o, conaddr, data, data_len);
} else {
// move connection to front of the list
LinkedList1_Remove(&o->connections_list, &con->connections_list_node);
LinkedList1_Append(&o->connections_list, &con->connections_list_node);
// send packet to existing connection
connection_send(con, data, data_len);
}
#else
// submit to udpgw client
UdpGwClient_SubmitPacket(&o->udpgw_client, local_addr, remote_addr, is_dns, data, data_len);
#endif
}
......@@ -32,8 +32,20 @@
#include <misc/debug.h>
#include <base/DebugObject.h>
#include <system/BReactor.h>
#ifdef BADVPN_SOCKS_UDP_RELAY
#include <protocol/udpgw_proto.h>
#include <protocol/packetproto.h>
#include <system/BDatagram.h>
#include <flow/PacketBuffer.h>
#include <flow/SinglePacketBuffer.h>
#include <flow/BufferWriter.h>
#include <structure/BAVL.h>
#include <structure/LinkedList1.h>
#include <misc/offset.h>
#else
#include <udpgw_client/UdpGwClient.h>
#include <socksclient/BSocksClient.h>
#endif
typedef void (*SocksUdpGwClient_handler_received) (void *user, BAddr local_addr, BAddr remote_addr, const uint8_t *data, int data_len);
......@@ -46,14 +58,44 @@ typedef struct {
BReactor *reactor;
void *user;
SocksUdpGwClient_handler_received handler_received;
#ifdef BADVPN_SOCKS_UDP_RELAY
int udpgw_mtu;
int num_connections;
int max_connections;
BAVL connections_tree;
LinkedList1 connections_list;
#else
UdpGwClient udpgw_client;
BTimer reconnect_timer;
int have_socks;
BSocksClient socks_client;
int socks_up;
#endif
DebugObject d_obj;
} SocksUdpGwClient;
#ifdef BADVPN_SOCKS_UDP_RELAY
typedef struct {
BAddr local_addr;
BAddr remote_addr;
} SocksUdpGwClient_conaddr;
typedef struct {
SocksUdpGwClient *client;
SocksUdpGwClient_conaddr conaddr;
BPending first_job;
const uint8_t *first_data;
int first_data_len;
BDatagram udp_dgram;
BufferWriter udp_send_writer;
PacketBuffer udp_send_buffer;
SinglePacketBuffer udp_recv_buffer;
PacketPassInterface udp_recv_if;
BAVLNode connections_tree_node;
LinkedList1Node connections_list_node;
} SocksUdpGwClient_connection;
#endif
int SocksUdpGwClient_Init (SocksUdpGwClient *o, int udp_mtu, int max_connections, int send_buffer_size, btime_t keepalive_time,
BAddr socks_server_addr, const struct BSocksClient_auth_info *auth_info, size_t num_auth_info,
BAddr remote_udpgw_addr, btime_t reconnect_time, BReactor *reactor, void *user,
......
......@@ -585,10 +585,15 @@ void print_help (const char *name)
" [--password <password>]\n"
" [--password-file <file>]\n"
" [--append-source-to-username]\n"
#ifdef ANDROID
" [--enable-udprelay]\n"
" [--udprelay-max-connections <number>]\n"
#else
" [--udpgw-remote-server-addr <addr>]\n"
" [--udpgw-max-connections <number>]\n"
" [--udpgw-connection-buffer-size <number>]\n"
" [--udpgw-transparent-dns]\n"
#endif
"Address format is a.b.c.d:port (IPv4) or [addr]:port (IPv6).\n",
name
);
......@@ -820,6 +825,10 @@ int parse_arguments (int argc, char *argv[])
else if (!strcmp(arg, "--append-source-to-username")) {
options.append_source_to_username = 1;
}
#ifdef ANDROID
else if (!strcmp(arg, "--enable-udprelay")) {
options.udpgw_remote_server_addr = "0.0.0.0:0";
#else
else if (!strcmp(arg, "--udpgw-remote-server-addr")) {
if (1 >= argc - i) {
fprintf(stderr, "%s: requires an argument\n", arg);
......@@ -827,8 +836,13 @@ int parse_arguments (int argc, char *argv[])
}
options.udpgw_remote_server_addr = argv[i + 1];
i++;
#endif
}
#ifdef ANDROID
else if (!strcmp(arg, "--udprelay-max-connections")) {
#else
else if (!strcmp(arg, "--udpgw-max-connections")) {
#endif
if (1 >= argc - i) {
fprintf(stderr, "%s: requires an argument\n", arg);
return 0;
......@@ -839,6 +853,7 @@ int parse_arguments (int argc, char *argv[])
}
i++;
}
#ifndef ANDROID
else if (!strcmp(arg, "--udpgw-connection-buffer-size")) {
if (1 >= argc - i) {
fprintf(stderr, "%s: requires an argument\n", arg);
......@@ -853,6 +868,7 @@ int parse_arguments (int argc, char *argv[])
else if (!strcmp(arg, "--udpgw-transparent-dns")) {
options.udpgw_transparent_dns = 1;
}
#endif
else {
fprintf(stderr, "unknown option: %s\n", arg);
return 0;
......@@ -959,7 +975,11 @@ int process_arguments (void)
// resolve remote udpgw server address
if (options.udpgw_remote_server_addr) {
if (!BAddr_Parse2(&udpgw_remote_server_addr, options.udpgw_remote_server_addr, NULL, 0, 0)) {
#ifdef ANDROID
BLog(BLOG_ERROR, "udprelay server addr: BAddr_Parse2 failed");
#else
BLog(BLOG_ERROR, "remote udpgw server addr: BAddr_Parse2 failed");
#endif
return 0;
}
}
......@@ -2080,7 +2100,11 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
switch (local_addr.type) {
case BADDR_TYPE_IPV4: {
#ifdef ANDROID
BLog(BLOG_INFO, "UDP: from udprelay %d bytes", data_len);
#else
BLog(BLOG_INFO, "UDP: from udpgw %d bytes", data_len);
#endif
if (data_len > UINT16_MAX - (sizeof(struct ipv4_header) + sizeof(struct udp_header)) ||
data_len > BTap_GetMTU(&device) - (int)(sizeof(struct ipv4_header) + sizeof(struct udp_header))
......@@ -2119,10 +2143,18 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
} break;
case BADDR_TYPE_IPV6: {
#ifdef ANDROID
BLog(BLOG_INFO, "UDP/IPv6: from udprelay %d bytes", data_len);
#else
BLog(BLOG_INFO, "UDP/IPv6: from udpgw %d bytes", data_len);
#endif
if (!options.netif_ip6addr) {
#ifdef ANDROID
BLog(BLOG_ERROR, "got IPv6 packet from udprelay but IPv6 is disabled");
#else
BLog(BLOG_ERROR, "got IPv6 packet from udpgw but IPv6 is disabled");
#endif
return;
}
......
......@@ -77,7 +77,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
def startShadowsocksDaemon() {
val cmd: String = (Path.BASE +
"ss-local -b 127.0.0.1 -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -f " +
"ss-local -b 127.0.0.1 -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -u -f " +
Path.BASE + "ss-local.pid")
.format(config.proxy, config.remotePort, config.localPort, config.sitekey, config.encMethod)
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
......@@ -186,18 +186,24 @@ class ShadowsocksVpnService extends VpnService with BaseService {
val fd = conn.getFd
val cmd = (Path.BASE +
var cmd = (Path.BASE +
"tun2socks --netif-ipaddr %s "
+ "--dnsgw %s:8153 "
+ "--netif-netmask 255.255.255.0 "
+ "--socks-server-addr 127.0.0.1:%d "
+ "--tunfd %d "
+ "--tunmtu %d "
+ "--loglevel 3 "
+ "--loglevel 5 "
+ "--pid %stun2socks.pid")
.format(PRIVATE_VLAN.format("2"), PRIVATE_VLAN.format("1"), config.localPort, fd, VPN_MTU,
Path.BASE)
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
.format(PRIVATE_VLAN.format("2"), config.localPort, fd, VPN_MTU, Path.BASE)
if (config.isUdpDns)
cmd += " --enable-udprelay"
else
cmd += " --dnsgw %s:8153".format(PRIVATE_VLAN.format("1"))
if (BuildConfig.DEBUG)
Log.d(TAG, cmd)
System.exec(cmd)
}
......@@ -205,7 +211,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
def handleConnection: Boolean = {
startVpn()
startShadowsocksDaemon()
startDnsDaemon()
if (!config.isUdpDns) startDnsDaemon()
true
}
......
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