Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
com.ccwangluo.accelerator
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sheteng
com.ccwangluo.accelerator
Commits
383e9404
Commit
383e9404
authored
Nov 24, 2014
by
Max Lv
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Run tun2socks in seprate process for now
parent
16d2cd9a
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
298 additions
and
318 deletions
+298
-318
.gitignore
.gitignore
+1
-0
.travis.yml
.travis.yml
+1
-0
README.md
README.md
+6
-0
build.sh
build.sh
+1
-1
project/plugins.sbt
project/plugins.sbt
+3
-1
src/main/AndroidManifest.xml
src/main/AndroidManifest.xml
+2
-3
src/main/java/com/github/shadowsocks/Tun2Socks.java
src/main/java/com/github/shadowsocks/Tun2Socks.java
+1
-1
src/main/jni/Android.mk
src/main/jni/Android.mk
+3
-3
src/main/jni/badvpn/tun2socks/tun2socks.c
src/main/jni/badvpn/tun2socks/tun2socks.c
+260
-291
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
+1
-1
src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala
.../scala/com/github/shadowsocks/ShadowsocksVpnService.scala
+19
-17
No files found.
.gitignore
View file @
383e9404
...
@@ -23,6 +23,7 @@ local.sbt
...
@@ -23,6 +23,7 @@ local.sbt
out/
out/
#NDK
#NDK
src/main/obj
src/main/libs
src/main/libs
src/main/assets/armeabi
src/main/assets/armeabi
src/main/assets/armeabi-v7a
src/main/assets/armeabi-v7a
...
...
.travis.yml
View file @
383e9404
...
@@ -18,5 +18,6 @@ install:
...
@@ -18,5 +18,6 @@ install:
-
echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a
-
echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a
script
:
script
:
-
cp local.properties.travis local.properties
-
cp local.properties.travis local.properties
-
./build.sh
-
sbt android:package-release
-
sbt android:package-release
-
exit
0
-
exit
0
README.md
View file @
383e9404
...
@@ -28,6 +28,9 @@ Help to translate shadowsocks: http://crowdin.net/project/shadowsocks/invite
...
@@ -28,6 +28,9 @@ Help to translate shadowsocks: http://crowdin.net/project/shadowsocks/invite
```
bash
```
bash
git submodule update
--init
git submodule update
--init
# Build native binaries
./build.sh
# Build the App
# Build the App
sbt clean android:package-release
sbt clean android:package-release
...
@@ -47,6 +50,9 @@ Help to translate shadowsocks: http://crowdin.net/project/shadowsocks/invite
...
@@ -47,6 +50,9 @@ Help to translate shadowsocks: http://crowdin.net/project/shadowsocks/invite
```
bash
```
bash
git submodule update
--init
git submodule update
--init
# Build native binaries
./build.sh
# Build the apk
# Build the apk
sbt clean android:package-release
sbt clean android:package-release
```
```
...
...
build.sh
View file @
383e9404
...
@@ -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
tun2socks
for
app
in
pdnsd redsocks ss-local ss-tunnel
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/
...
...
project/plugins.sbt
View file @
383e9404
...
@@ -2,4 +2,6 @@ resolvers += Resolver.url("scalasbt releases", new URL("http://scalasbt.artifact
...
@@ -2,4 +2,6 @@ resolvers += Resolver.url("scalasbt releases", new URL("http://scalasbt.artifact
addSbtPlugin
(
"com.hanhuy.sbt"
%
"android-sdk-plugin"
%
"1.3.10"
)
addSbtPlugin
(
"com.hanhuy.sbt"
%
"android-sdk-plugin"
%
"1.3.10"
)
addSbtPlugin
(
"com.github.mpeltonen"
%
"sbt-idea"
%
"1.6.0"
)
resolvers
+=
Resolver
.
sbtPluginRepo
(
"snapshots"
)
addSbtPlugin
(
"com.hanhuy.sbt"
%
"sbt-idea"
%
"1.7.0-SNAPSHOT"
)
src/main/AndroidManifest.xml
View file @
383e9404
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
package=
"com.github.shadowsocks"
package=
"com.github.shadowsocks"
android:versionCode=
"8
4
"
android:versionCode=
"8
5
"
android:versionName=
"2.4.
4
"
>
android:versionName=
"2.4.
5
"
>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.ACCESS_NETWORK_STATE"
/>
<uses-permission
android:name=
"android.permission.ACCESS_NETWORK_STATE"
/>
...
@@ -18,7 +18,6 @@
...
@@ -18,7 +18,6 @@
<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"
...
...
src/main/java/com/github/shadowsocks/Tun2Socks.java
View file @
383e9404
...
@@ -40,7 +40,7 @@ package com.github.shadowsocks;
...
@@ -40,7 +40,7 @@ package com.github.shadowsocks;
public
class
Tun2Socks
{
public
class
Tun2Socks
{
static
{
static
{
java
.
lang
.
System
.
loadLibrary
(
"tun2socks
-jni
"
);
java
.
lang
.
System
.
loadLibrary
(
"tun2socks"
);
}
}
public
static
native
void
start
(
String
[]
cmd
);
public
static
native
void
start
(
String
[]
cmd
);
...
...
src/main/jni/Android.mk
View file @
383e9404
...
@@ -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
\
...
@@ -288,9 +288,9 @@ LOCAL_MODULE := tun2socks
...
@@ -288,9 +288,9 @@ LOCAL_MODULE := tun2socks
LOCAL_LDLIBS
:=
-ldl
-llog
LOCAL_LDLIBS
:=
-ldl
-llog
LOCAL_SRC_FILES
:=
$(
addprefix
badvpn/,
$(TUN2SOCKS_SOURCES)
)
LOCAL_SRC_FILES
:=
$(
addprefix
badvpn/,
$(TUN2SOCKS_SOURCES)
)
tun2socks-jni.cpp
include
$(BUILD_
EXECUTABLE
)
include
$(BUILD_
SHARED_LIBRARY
)
# OpenSSL
# OpenSSL
openssl_subdirs
:=
$(
addprefix
$(LOCAL_PATH)
/openssl/,
$(
addsuffix
/Android.mk,
\
openssl_subdirs
:=
$(
addprefix
$(LOCAL_PATH)
/openssl/,
$(
addsuffix
/Android.mk,
\
...
...
src/main/jni/badvpn/tun2socks/tun2socks.c
View file @
383e9404
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* Copyright (C) Ambroz Bizjak <ambrop7@gmail.com>
* Copyright (C) Ambroz Bizjak <ambrop7@gmail.com>
* Contributions:
* Contributions:
* Transparent DNS: Copyright (C) Kerem Hadimli <kerem.hadimli@gmail.com>
* Transparent DNS: Copyright (C) Kerem Hadimli <kerem.hadimli@gmail.com>
*
*
* Redistribution and use in source and binary forms, with or without
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* 1. Redistributions of source code must retain the above copyright
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
* 3. Neither the name of the author nor the
* 3. Neither the name of the author nor the
* names of its contributors may be used to endorse or promote products
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* 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
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
...
@@ -183,8 +183,6 @@ sock_fd_write(int sock, void *buf, ssize_t buflen, int fd)
...
@@ -183,8 +183,6 @@ sock_fd_write(int sock, void *buf, ssize_t buflen, int fd)
size
=
sendmsg
(
sock
,
&
msg
,
0
);
size
=
sendmsg
(
sock
,
&
msg
,
0
);
if
(
size
<
0
)
perror
(
"sendmsg"
);
return
size
;
return
size
;
}
}
...
@@ -213,7 +211,6 @@ sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd)
...
@@ -213,7 +211,6 @@ sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd)
msg
.
msg_controllen
=
sizeof
(
cmsgu
.
control
);
msg
.
msg_controllen
=
sizeof
(
cmsgu
.
control
);
size
=
recvmsg
(
sock
,
&
msg
,
0
);
size
=
recvmsg
(
sock
,
&
msg
,
0
);
if
(
size
<
0
)
{
if
(
size
<
0
)
{
perror
(
"recvmsg"
);
return
-
1
;
return
-
1
;
}
}
cmsg
=
CMSG_FIRSTHDR
(
&
msg
);
cmsg
=
CMSG_FIRSTHDR
(
&
msg
);
...
@@ -450,7 +447,7 @@ static void daemonize(const char* path) {
...
@@ -450,7 +447,7 @@ static void daemonize(const char* path) {
/* Change the file mode mask */
/* Change the file mode mask */
umask
(
0
);
umask
(
0
);
/* Open any logs here */
/* Open any logs here */
/* Create a new SID for the child process */
/* Create a new SID for the child process */
sid
=
setsid
();
sid
=
setsid
();
...
@@ -474,10 +471,9 @@ static void daemonize(const char* path) {
...
@@ -474,10 +471,9 @@ static void daemonize(const char* path) {
int
int
recv_tun_fd
(
void
)
recv_tun_fd
(
void
)
{
{
int
s_fd
,
c_fd
,
fd_to_read
;
int
s_fd
,
fd_to_read
;
struct
sockaddr_un
addr
;
struct
sockaddr_un
addr
;
socklen_t
addr_len
;
socklen_t
addr_len
;
char
buf
[
16
];
s_fd
=
socket
(
AF_UNIX
,
SOCK_STREAM
,
0
);
s_fd
=
socket
(
AF_UNIX
,
SOCK_STREAM
,
0
);
if
(
s_fd
<
0
)
{
if
(
s_fd
<
0
)
{
...
@@ -490,42 +486,25 @@ recv_tun_fd (void)
...
@@ -490,42 +486,25 @@ recv_tun_fd (void)
addr_len
=
sizeof
(
struct
sockaddr_un
);
addr_len
=
sizeof
(
struct
sockaddr_un
);
memset
(
&
addr
,
0
,
addr_len
);
memset
(
&
addr
,
0
,
addr_len
);
addr
.
sun_family
=
AF_UNIX
;
addr
.
sun_family
=
AF_UNIX
;
snprintf
(
addr
.
sun_path
+
1
,
14
,
"tun2socks"
);
addr
.
sun_path
[
0
]
=
'\0'
;
strcpy
(
addr
.
sun_path
+
1
,
"tun2socks"
);
if
(
bind
(
s_fd
,
(
struct
sockaddr
*
)
&
addr
,
addr_len
)
!=
0
)
if
(
connect
(
s_fd
,
(
struct
sockaddr
*
)
&
addr
,
addr_len
)
!=
-
1
)
{
{
BLog
(
BLOG_ERROR
,
"Error to bind local socket"
);
char
buf
[
16
];
close
(
s_fd
);
return
-
1
;
}
BLog
(
BLOG_NOTICE
,
"Bind socket
"
);
BLog
(
BLOG_NOTICE
,
"Connected
"
);
if
(
listen
(
s_fd
,
5
)
!=
0
)
read
(
s_fd
,
buf
,
1
);
{
sock_fd_read
(
s_fd
,
buf
,
sizeof
(
buf
),
&
fd_to_read
);
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
;
buf
[
0
]
=
0
;
write
(
c
_fd
,
buf
,
1
);
write
(
s
_fd
,
buf
,
1
);
close
(
c
_fd
);
close
(
s
_fd
);
}
}
else
else
{
{
BLog
(
BLOG_ERROR
,
"Error to
accept socket"
);
BLog
(
BLOG_ERROR
,
"Error to
connect: %s"
,
strerror
(
errno
)
);
close
(
s_fd
);
close
(
s_fd
);
return
-
1
;
return
-
1
;
}
}
...
@@ -543,17 +522,17 @@ int main (int argc, char **argv)
...
@@ -543,17 +522,17 @@ int main (int argc, char **argv)
if
(
argc
<=
0
)
{
if
(
argc
<=
0
)
{
return
1
;
return
1
;
}
}
// open standard streams
// open standard streams
open_standard_streams
();
open_standard_streams
();
// parse command-line arguments
// parse command-line arguments
if
(
!
parse_arguments
(
argc
,
argv
))
{
if
(
!
parse_arguments
(
argc
,
argv
))
{
fprintf
(
stderr
,
"Failed to parse arguments
\n
"
);
fprintf
(
stderr
,
"Failed to parse arguments
\n
"
);
print_help
(
argv
[
0
]);
print_help
(
argv
[
0
]);
goto
fail0
;
goto
fail0
;
}
}
// handle --help and --version
// handle --help and --version
if
(
options
.
help
)
{
if
(
options
.
help
)
{
print_version
();
print_version
();
...
@@ -581,7 +560,7 @@ int main (int argc, char **argv)
...
@@ -581,7 +560,7 @@ int main (int argc, char **argv)
default:
default:
ASSERT
(
0
);
ASSERT
(
0
);
}
}
// configure logger channels
// configure logger channels
for
(
int
i
=
0
;
i
<
BLOG_NUM_CHANNELS
;
i
++
)
{
for
(
int
i
=
0
;
i
<
BLOG_NUM_CHANNELS
;
i
++
)
{
if
(
options
.
loglevels
[
i
]
>=
0
)
{
if
(
options
.
loglevels
[
i
]
>=
0
)
{
...
@@ -598,52 +577,41 @@ int main (int argc, char **argv)
...
@@ -598,52 +577,41 @@ int main (int argc, char **argv)
if
(
options
.
pid
)
{
if
(
options
.
pid
)
{
daemonize
(
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
#endif
// clear password contents pointer
// clear password contents pointer
password_file_contents
=
NULL
;
password_file_contents
=
NULL
;
// initialize network
// initialize network
if
(
!
BNetwork_GlobalInit
())
{
if
(
!
BNetwork_GlobalInit
())
{
BLog
(
BLOG_ERROR
,
"BNetwork_GlobalInit failed"
);
BLog
(
BLOG_ERROR
,
"BNetwork_GlobalInit failed"
);
goto
fail1
;
goto
fail1
;
}
}
// process arguments
// process arguments
if
(
!
process_arguments
())
{
if
(
!
process_arguments
())
{
BLog
(
BLOG_ERROR
,
"Failed to process arguments"
);
BLog
(
BLOG_ERROR
,
"Failed to process arguments"
);
goto
fail1
;
goto
fail1
;
}
}
// init time
// init time
BTime_Init
();
BTime_Init
();
// init reactor
// init reactor
if
(
!
BReactor_Init
(
&
ss
))
{
if
(
!
BReactor_Init
(
&
ss
))
{
BLog
(
BLOG_ERROR
,
"BReactor_Init failed"
);
BLog
(
BLOG_ERROR
,
"BReactor_Init failed"
);
goto
fail1
;
goto
fail1
;
}
}
// set not quitting
// set not quitting
quitting
=
0
;
quitting
=
0
;
// setup signal handler
// setup signal handler
if
(
!
BSignal_Init
(
&
ss
,
signal_handler
,
NULL
))
{
if
(
!
BSignal_Init
(
&
ss
,
signal_handler
,
NULL
))
{
BLog
(
BLOG_ERROR
,
"BSignal_Init failed"
);
BLog
(
BLOG_ERROR
,
"BSignal_Init failed"
);
goto
fail2
;
goto
fail2
;
}
}
#ifdef ANDROID
#ifdef ANDROID
// use supplied file descriptor
// use supplied file descriptor
...
@@ -652,7 +620,7 @@ int main (int argc, char **argv)
...
@@ -652,7 +620,7 @@ int main (int argc, char **argv)
init_data
.
init_type
=
BTAP_INIT_FD
;
init_data
.
init_type
=
BTAP_INIT_FD
;
init_data
.
init
.
fd
.
fd
=
options
.
tun_fd
;
init_data
.
init
.
fd
.
fd
=
options
.
tun_fd
;
init_data
.
init
.
fd
.
mtu
=
options
.
tun_mtu
;
init_data
.
init
.
fd
.
mtu
=
options
.
tun_mtu
;
if
(
!
BTap_Init2
(
&
device
,
&
ss
,
init_data
,
device_error_handler
,
NULL
))
{
if
(
!
BTap_Init2
(
&
device
,
&
ss
,
init_data
,
device_error_handler
,
NULL
))
{
BLog
(
BLOG_ERROR
,
"BTap_Init2 failed"
);
BLog
(
BLOG_ERROR
,
"BTap_Init2 failed"
);
goto
fail3
;
goto
fail3
;
...
@@ -664,19 +632,19 @@ int main (int argc, char **argv)
...
@@ -664,19 +632,19 @@ int main (int argc, char **argv)
goto
fail3
;
goto
fail3
;
}
}
#endif
#endif
// NOTE: the order of the following is important:
// NOTE: the order of the following is important:
// first device writing must evaluate,
// first device writing must evaluate,
// then lwip (so it can send packets to the device),
// then lwip (so it can send packets to the device),
// then device reading (so it can pass received packets to lwip).
// then device reading (so it can pass received packets to lwip).
// init device reading
// init device reading
PacketPassInterface_Init
(
&
device_read_interface
,
BTap_GetMTU
(
&
device
),
device_read_handler_send
,
NULL
,
BReactor_PendingGroup
(
&
ss
));
PacketPassInterface_Init
(
&
device_read_interface
,
BTap_GetMTU
(
&
device
),
device_read_handler_send
,
NULL
,
BReactor_PendingGroup
(
&
ss
));
if
(
!
SinglePacketBuffer_Init
(
&
device_read_buffer
,
BTap_GetOutput
(
&
device
),
&
device_read_interface
,
BReactor_PendingGroup
(
&
ss
)))
{
if
(
!
SinglePacketBuffer_Init
(
&
device_read_buffer
,
BTap_GetOutput
(
&
device
),
&
device_read_interface
,
BReactor_PendingGroup
(
&
ss
)))
{
BLog
(
BLOG_ERROR
,
"SinglePacketBuffer_Init failed"
);
BLog
(
BLOG_ERROR
,
"SinglePacketBuffer_Init failed"
);
goto
fail4
;
goto
fail4
;
}
}
if
(
options
.
udpgw_remote_server_addr
)
{
if
(
options
.
udpgw_remote_server_addr
)
{
// compute maximum UDP payload size we need to pass through udpgw
// compute maximum UDP payload size we need to pass through udpgw
udp_mtu
=
BTap_GetMTU
(
&
device
)
-
(
int
)(
sizeof
(
struct
ipv4_header
)
+
sizeof
(
struct
udp_header
));
udp_mtu
=
BTap_GetMTU
(
&
device
)
-
(
int
)(
sizeof
(
struct
ipv4_header
)
+
sizeof
(
struct
udp_header
));
...
@@ -689,14 +657,14 @@ int main (int argc, char **argv)
...
@@ -689,14 +657,14 @@ int main (int argc, char **argv)
if
(
udp_mtu
<
0
)
{
if
(
udp_mtu
<
0
)
{
udp_mtu
=
0
;
udp_mtu
=
0
;
}
}
// make sure our UDP payloads aren't too large for udpgw
// make sure our UDP payloads aren't too large for udpgw
int
udpgw_mtu
=
udpgw_compute_mtu
(
udp_mtu
);
int
udpgw_mtu
=
udpgw_compute_mtu
(
udp_mtu
);
if
(
udpgw_mtu
<
0
||
udpgw_mtu
>
PACKETPROTO_MAXPAYLOAD
)
{
if
(
udpgw_mtu
<
0
||
udpgw_mtu
>
PACKETPROTO_MAXPAYLOAD
)
{
BLog
(
BLOG_ERROR
,
"device MTU is too large for UDP"
);
BLog
(
BLOG_ERROR
,
"device MTU is too large for UDP"
);
goto
fail4a
;
goto
fail4a
;
}
}
// init udpgw client
// init udpgw client
if
(
!
SocksUdpGwClient_Init
(
&
udpgw_client
,
udp_mtu
,
DEFAULT_UDPGW_MAX_CONNECTIONS
,
options
.
udpgw_connection_buffer_size
,
UDPGW_KEEPALIVE_TIME
,
if
(
!
SocksUdpGwClient_Init
(
&
udpgw_client
,
udp_mtu
,
DEFAULT_UDPGW_MAX_CONNECTIONS
,
options
.
udpgw_connection_buffer_size
,
UDPGW_KEEPALIVE_TIME
,
socks_server_addr
,
socks_auth_info
,
socks_num_auth_info
,
socks_server_addr
,
socks_auth_info
,
socks_num_auth_info
,
...
@@ -706,46 +674,46 @@ int main (int argc, char **argv)
...
@@ -706,46 +674,46 @@ int main (int argc, char **argv)
goto
fail4a
;
goto
fail4a
;
}
}
}
}
// init lwip init job
// init lwip init job
BPending_Init
(
&
lwip_init_job
,
BReactor_PendingGroup
(
&
ss
),
lwip_init_job_hadler
,
NULL
);
BPending_Init
(
&
lwip_init_job
,
BReactor_PendingGroup
(
&
ss
),
lwip_init_job_hadler
,
NULL
);
BPending_Set
(
&
lwip_init_job
);
BPending_Set
(
&
lwip_init_job
);
// init device write buffer
// init device write buffer
if
(
!
(
device_write_buf
=
(
uint8_t
*
)
BAlloc
(
BTap_GetMTU
(
&
device
))))
{
if
(
!
(
device_write_buf
=
(
uint8_t
*
)
BAlloc
(
BTap_GetMTU
(
&
device
))))
{
BLog
(
BLOG_ERROR
,
"BAlloc failed"
);
BLog
(
BLOG_ERROR
,
"BAlloc failed"
);
goto
fail5
;
goto
fail5
;
}
}
// init TCP timer
// init TCP timer
// it won't trigger before lwip is initialized, becuase the lwip init is a job
// it won't trigger before lwip is initialized, becuase the lwip init is a job
BTimer_Init
(
&
tcp_timer
,
TCP_TMR_INTERVAL
,
tcp_timer_handler
,
NULL
);
BTimer_Init
(
&
tcp_timer
,
TCP_TMR_INTERVAL
,
tcp_timer_handler
,
NULL
);
BReactor_SetTimer
(
&
ss
,
&
tcp_timer
);
BReactor_SetTimer
(
&
ss
,
&
tcp_timer
);
// set no netif
// set no netif
have_netif
=
0
;
have_netif
=
0
;
// set no listener
// set no listener
listener
=
NULL
;
listener
=
NULL
;
listener_ip6
=
NULL
;
listener_ip6
=
NULL
;
// init clients list
// init clients list
LinkedList1_Init
(
&
tcp_clients
);
LinkedList1_Init
(
&
tcp_clients
);
// init number of clients
// init number of clients
num_clients
=
0
;
num_clients
=
0
;
// enter event loop
// enter event loop
BLog
(
BLOG_NOTICE
,
"entering event loop"
);
BLog
(
BLOG_NOTICE
,
"entering event loop"
);
BReactor_Exec
(
&
ss
);
BReactor_Exec
(
&
ss
);
// free clients
// free clients
LinkedList1Node
*
node
;
LinkedList1Node
*
node
;
while
(
node
=
LinkedList1_GetFirst
(
&
tcp_clients
))
{
while
(
node
=
LinkedList1_GetFirst
(
&
tcp_clients
))
{
struct
tcp_client
*
client
=
UPPER_OBJECT
(
node
,
struct
tcp_client
,
list_node
);
struct
tcp_client
*
client
=
UPPER_OBJECT
(
node
,
struct
tcp_client
,
list_node
);
client_murder
(
client
);
client_murder
(
client
);
}
}
// free listener
// free listener
if
(
listener_ip6
)
{
if
(
listener_ip6
)
{
tcp_close
(
listener_ip6
);
tcp_close
(
listener_ip6
);
...
@@ -753,22 +721,23 @@ int main (int argc, char **argv)
...
@@ -753,22 +721,23 @@ int main (int argc, char **argv)
if
(
listener
)
{
if
(
listener
)
{
tcp_close
(
listener
);
tcp_close
(
listener
);
}
}
// free netif
// free netif
if
(
have_netif
)
{
if
(
have_netif
)
{
netif_remove
(
&
netif
);
netif_remove
(
&
netif
);
}
}
BReactor_RemoveTimer
(
&
ss
,
&
tcp_timer
);
BFree
(
device_write_buf
);
#ifdef ANDROID
#ifdef ANDROID
BLog
(
BLOG_NOTICE
,
"Free TCP connections"
);
tcp_remove
(
tcp_bound_pcbs
);
tcp_remove
(
tcp_bound_pcbs
);
tcp_remove
(
tcp_active_pcbs
);
tcp_remove
(
tcp_active_pcbs
);
tcp_remove
(
tcp_tw_pcbs
);
tcp_remove
(
tcp_tw_pcbs
);
free_connections
();
free_connections
();
#endif
#endif
BReactor_RemoveTimer
(
&
ss
,
&
tcp_timer
);
BFree
(
device_write_buf
);
fail5:
fail5:
BPending_Free
(
&
lwip_init_job
);
BPending_Free
(
&
lwip_init_job
);
if
(
options
.
udpgw_remote_server_addr
)
{
if
(
options
.
udpgw_remote_server_addr
)
{
...
@@ -789,19 +758,19 @@ fail1:
...
@@ -789,19 +758,19 @@ fail1:
BLog_Free
();
BLog_Free
();
fail0:
fail0:
DebugObjectGlobal_Finish
();
DebugObjectGlobal_Finish
();
return
1
;
return
1
;
}
}
void
terminate
(
void
)
void
terminate
(
void
)
{
{
ASSERT
(
!
quitting
)
ASSERT
(
!
quitting
)
BLog
(
BLOG_NOTICE
,
"tearing down"
);
BLog
(
BLOG_NOTICE
,
"tearing down"
);
// set quitting
// set quitting
quitting
=
1
;
quitting
=
1
;
// exit event loop
// exit event loop
BReactor_Quit
(
&
ss
,
1
);
BReactor_Quit
(
&
ss
,
1
);
}
}
...
@@ -862,7 +831,7 @@ int parse_arguments (int argc, char *argv[])
...
@@ -862,7 +831,7 @@ int parse_arguments (int argc, char *argv[])
if
(
argc
<=
0
)
{
if
(
argc
<=
0
)
{
return
0
;
return
0
;
}
}
options
.
help
=
0
;
options
.
help
=
0
;
options
.
version
=
0
;
options
.
version
=
0
;
options
.
logger
=
LOGGER_STDOUT
;
options
.
logger
=
LOGGER_STDOUT
;
...
@@ -893,7 +862,7 @@ int parse_arguments (int argc, char *argv[])
...
@@ -893,7 +862,7 @@ int parse_arguments (int argc, char *argv[])
options
.
udpgw_max_connections
=
DEFAULT_UDPGW_MAX_CONNECTIONS
;
options
.
udpgw_max_connections
=
DEFAULT_UDPGW_MAX_CONNECTIONS
;
options
.
udpgw_connection_buffer_size
=
DEFAULT_UDPGW_CONNECTION_BUFFER_SIZE
;
options
.
udpgw_connection_buffer_size
=
DEFAULT_UDPGW_CONNECTION_BUFFER_SIZE
;
options
.
udpgw_transparent_dns
=
0
;
options
.
udpgw_transparent_dns
=
0
;
int
i
;
int
i
;
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
char
*
arg
=
argv
[
i
];
char
*
arg
=
argv
[
i
];
...
@@ -1078,7 +1047,7 @@ int parse_arguments (int argc, char *argv[])
...
@@ -1078,7 +1047,7 @@ int parse_arguments (int argc, char *argv[])
else
if
(
!
strcmp
(
arg
,
"--append-source-to-username"
))
{
else
if
(
!
strcmp
(
arg
,
"--append-source-to-username"
))
{
options
.
append_source_to_username
=
1
;
options
.
append_source_to_username
=
1
;
}
}
#ifdef ANDROID
#ifdef ANDROID
else
if
(
!
strcmp
(
arg
,
"--enable-udprelay"
))
{
else
if
(
!
strcmp
(
arg
,
"--enable-udprelay"
))
{
options
.
udpgw_remote_server_addr
=
"0.0.0.0:0"
;
options
.
udpgw_remote_server_addr
=
"0.0.0.0:0"
;
#else
#else
...
@@ -1127,38 +1096,38 @@ int parse_arguments (int argc, char *argv[])
...
@@ -1127,38 +1096,38 @@ int parse_arguments (int argc, char *argv[])
return
0
;
return
0
;
}
}
}
}
if
(
options
.
help
||
options
.
version
)
{
if
(
options
.
help
||
options
.
version
)
{
return
1
;
return
1
;
}
}
if
(
!
options
.
netif_ipaddr
)
{
if
(
!
options
.
netif_ipaddr
)
{
fprintf
(
stderr
,
"--netif-ipaddr is required
\n
"
);
fprintf
(
stderr
,
"--netif-ipaddr is required
\n
"
);
return
0
;
return
0
;
}
}
if
(
!
options
.
netif_netmask
)
{
if
(
!
options
.
netif_netmask
)
{
fprintf
(
stderr
,
"--netif-netmask is required
\n
"
);
fprintf
(
stderr
,
"--netif-netmask is required
\n
"
);
return
0
;
return
0
;
}
}
if
(
!
options
.
socks_server_addr
)
{
if
(
!
options
.
socks_server_addr
)
{
fprintf
(
stderr
,
"--socks-server-addr is required
\n
"
);
fprintf
(
stderr
,
"--socks-server-addr is required
\n
"
);
return
0
;
return
0
;
}
}
if
(
options
.
username
)
{
if
(
options
.
username
)
{
if
(
!
options
.
password
&&
!
options
.
password_file
)
{
if
(
!
options
.
password
&&
!
options
.
password_file
)
{
fprintf
(
stderr
,
"username given but password not given
\n
"
);
fprintf
(
stderr
,
"username given but password not given
\n
"
);
return
0
;
return
0
;
}
}
if
(
options
.
password
&&
options
.
password_file
)
{
if
(
options
.
password
&&
options
.
password_file
)
{
fprintf
(
stderr
,
"--password and --password-file cannot both be given
\n
"
);
fprintf
(
stderr
,
"--password and --password-file cannot both be given
\n
"
);
return
0
;
return
0
;
}
}
}
}
return
1
;
return
1
;
}
}
...
@@ -1175,7 +1144,7 @@ int process_arguments (void)
...
@@ -1175,7 +1144,7 @@ int process_arguments (void)
BLog
(
BLOG_ERROR
,
"netif ipaddr: must be an IPv4 address"
);
BLog
(
BLOG_ERROR
,
"netif ipaddr: must be an IPv4 address"
);
return
0
;
return
0
;
}
}
// resolve netif netmask
// resolve netif netmask
if
(
!
BIPAddr_Resolve
(
&
netif_netmask
,
options
.
netif_netmask
,
0
))
{
if
(
!
BIPAddr_Resolve
(
&
netif_netmask
,
options
.
netif_netmask
,
0
))
{
BLog
(
BLOG_ERROR
,
"netif netmask: BIPAddr_Resolve failed"
);
BLog
(
BLOG_ERROR
,
"netif netmask: BIPAddr_Resolve failed"
);
...
@@ -1185,7 +1154,7 @@ int process_arguments (void)
...
@@ -1185,7 +1154,7 @@ int process_arguments (void)
BLog
(
BLOG_ERROR
,
"netif netmask: must be an IPv4 address"
);
BLog
(
BLOG_ERROR
,
"netif netmask: must be an IPv4 address"
);
return
0
;
return
0
;
}
}
// parse IP6 address
// parse IP6 address
if
(
options
.
netif_ip6addr
)
{
if
(
options
.
netif_ip6addr
)
{
if
(
!
ipaddr6_parse_ipv6_addr
(
options
.
netif_ip6addr
,
&
netif_ip6addr
))
{
if
(
!
ipaddr6_parse_ipv6_addr
(
options
.
netif_ip6addr
,
&
netif_ip6addr
))
{
...
@@ -1193,17 +1162,17 @@ int process_arguments (void)
...
@@ -1193,17 +1162,17 @@ int process_arguments (void)
return
0
;
return
0
;
}
}
}
}
// resolve SOCKS server address
// resolve SOCKS server address
if
(
!
BAddr_Parse2
(
&
socks_server_addr
,
options
.
socks_server_addr
,
NULL
,
0
,
0
))
{
if
(
!
BAddr_Parse2
(
&
socks_server_addr
,
options
.
socks_server_addr
,
NULL
,
0
,
0
))
{
BLog
(
BLOG_ERROR
,
"socks server addr: BAddr_Parse2 failed"
);
BLog
(
BLOG_ERROR
,
"socks server addr: BAddr_Parse2 failed"
);
return
0
;
return
0
;
}
}
// add none socks authentication method
// add none socks authentication method
socks_auth_info
[
0
]
=
BSocksClient_auth_none
();
socks_auth_info
[
0
]
=
BSocksClient_auth_none
();
socks_num_auth_info
=
1
;
socks_num_auth_info
=
1
;
// add password socks authentication method
// add password socks authentication method
if
(
options
.
username
)
{
if
(
options
.
username
)
{
const
char
*
password
;
const
char
*
password
;
...
@@ -1218,13 +1187,13 @@ int process_arguments (void)
...
@@ -1218,13 +1187,13 @@ int process_arguments (void)
}
}
password
=
(
char
*
)
password_file_contents
;
password
=
(
char
*
)
password_file_contents
;
}
}
socks_auth_info
[
socks_num_auth_info
++
]
=
BSocksClient_auth_password
(
socks_auth_info
[
socks_num_auth_info
++
]
=
BSocksClient_auth_password
(
options
.
username
,
strlen
(
options
.
username
),
options
.
username
,
strlen
(
options
.
username
),
password
,
password_len
password
,
password_len
);
);
}
}
// resolve remote udpgw server address
// resolve remote udpgw server address
if
(
options
.
udpgw_remote_server_addr
)
{
if
(
options
.
udpgw_remote_server_addr
)
{
if
(
!
BAddr_Parse2
(
&
udpgw_remote_server_addr
,
options
.
udpgw_remote_server_addr
,
NULL
,
0
,
0
))
{
if
(
!
BAddr_Parse2
(
&
udpgw_remote_server_addr
,
options
.
udpgw_remote_server_addr
,
NULL
,
0
,
0
))
{
...
@@ -1250,16 +1219,16 @@ int process_arguments (void)
...
@@ -1250,16 +1219,16 @@ int process_arguments (void)
}
}
}
}
#endif
#endif
return
1
;
return
1
;
}
}
void
signal_handler
(
void
*
unused
)
void
signal_handler
(
void
*
unused
)
{
{
ASSERT
(
!
quitting
)
ASSERT
(
!
quitting
)
BLog
(
BLOG_NOTICE
,
"termination requested"
);
BLog
(
BLOG_NOTICE
,
"termination requested"
);
terminate
();
terminate
();
}
}
...
@@ -1282,15 +1251,15 @@ void lwip_init_job_hadler (void *unused)
...
@@ -1282,15 +1251,15 @@ void lwip_init_job_hadler (void *unused)
ASSERT
(
!
have_netif
)
ASSERT
(
!
have_netif
)
ASSERT
(
!
listener
)
ASSERT
(
!
listener
)
ASSERT
(
!
listener_ip6
)
ASSERT
(
!
listener_ip6
)
BLog
(
BLOG_DEBUG
,
"lwip init"
);
BLog
(
BLOG_DEBUG
,
"lwip init"
);
// NOTE: the device may fail during this, but there's no harm in not checking
// NOTE: the device may fail during this, but there's no harm in not checking
// for that at every step
// for that at every step
// init lwip
// init lwip
lwip_init
();
lwip_init
();
// make addresses for netif
// make addresses for netif
ip_addr_t
addr
;
ip_addr_t
addr
;
addr
.
addr
=
netif_ipaddr
.
ipv4
;
addr
.
addr
=
netif_ipaddr
.
ipv4
;
...
@@ -1298,77 +1267,77 @@ void lwip_init_job_hadler (void *unused)
...
@@ -1298,77 +1267,77 @@ void lwip_init_job_hadler (void *unused)
netmask
.
addr
=
netif_netmask
.
ipv4
;
netmask
.
addr
=
netif_netmask
.
ipv4
;
ip_addr_t
gw
;
ip_addr_t
gw
;
ip_addr_set_any
(
&
gw
);
ip_addr_set_any
(
&
gw
);
// init netif
// init netif
if
(
!
netif_add
(
&
netif
,
&
addr
,
&
netmask
,
&
gw
,
NULL
,
netif_init_func
,
netif_input_func
))
{
if
(
!
netif_add
(
&
netif
,
&
addr
,
&
netmask
,
&
gw
,
NULL
,
netif_init_func
,
netif_input_func
))
{
BLog
(
BLOG_ERROR
,
"netif_add failed"
);
BLog
(
BLOG_ERROR
,
"netif_add failed"
);
goto
fail
;
goto
fail
;
}
}
have_netif
=
1
;
have_netif
=
1
;
// set netif up
// set netif up
netif_set_up
(
&
netif
);
netif_set_up
(
&
netif
);
// set netif pretend TCP
// set netif pretend TCP
netif_set_pretend_tcp
(
&
netif
,
1
);
netif_set_pretend_tcp
(
&
netif
,
1
);
// set netif default
// set netif default
netif_set_default
(
&
netif
);
netif_set_default
(
&
netif
);
if
(
options
.
netif_ip6addr
)
{
if
(
options
.
netif_ip6addr
)
{
// add IPv6 address
// add IPv6 address
memcpy
(
netif_ip6_addr
(
&
netif
,
0
),
netif_ip6addr
.
bytes
,
sizeof
(
netif_ip6addr
.
bytes
));
memcpy
(
netif_ip6_addr
(
&
netif
,
0
),
netif_ip6addr
.
bytes
,
sizeof
(
netif_ip6addr
.
bytes
));
netif_ip6_addr_set_state
(
&
netif
,
0
,
IP6_ADDR_VALID
);
netif_ip6_addr_set_state
(
&
netif
,
0
,
IP6_ADDR_VALID
);
}
}
// init listener
// init listener
struct
tcp_pcb
*
l
=
tcp_new
();
struct
tcp_pcb
*
l
=
tcp_new
();
if
(
!
l
)
{
if
(
!
l
)
{
BLog
(
BLOG_ERROR
,
"tcp_new failed"
);
BLog
(
BLOG_ERROR
,
"tcp_new failed"
);
goto
fail
;
goto
fail
;
}
}
// bind listener
// bind listener
if
(
tcp_bind_to_netif
(
l
,
"ho0"
)
!=
ERR_OK
)
{
if
(
tcp_bind_to_netif
(
l
,
"ho0"
)
!=
ERR_OK
)
{
BLog
(
BLOG_ERROR
,
"tcp_bind_to_netif failed"
);
BLog
(
BLOG_ERROR
,
"tcp_bind_to_netif failed"
);
tcp_close
(
l
);
tcp_close
(
l
);
goto
fail
;
goto
fail
;
}
}
// listen listener
// listen listener
if
(
!
(
listener
=
tcp_listen
(
l
)))
{
if
(
!
(
listener
=
tcp_listen
(
l
)))
{
BLog
(
BLOG_ERROR
,
"tcp_listen failed"
);
BLog
(
BLOG_ERROR
,
"tcp_listen failed"
);
tcp_close
(
l
);
tcp_close
(
l
);
goto
fail
;
goto
fail
;
}
}
// setup listener accept handler
// setup listener accept handler
tcp_accept
(
listener
,
listener_accept_func
);
tcp_accept
(
listener
,
listener_accept_func
);
if
(
options
.
netif_ip6addr
)
{
if
(
options
.
netif_ip6addr
)
{
struct
tcp_pcb
*
l_ip6
=
tcp_new_ip6
();
struct
tcp_pcb
*
l_ip6
=
tcp_new_ip6
();
if
(
!
l_ip6
)
{
if
(
!
l_ip6
)
{
BLog
(
BLOG_ERROR
,
"tcp_new_ip6 failed"
);
BLog
(
BLOG_ERROR
,
"tcp_new_ip6 failed"
);
goto
fail
;
goto
fail
;
}
}
if
(
tcp_bind_to_netif
(
l_ip6
,
"ho0"
)
!=
ERR_OK
)
{
if
(
tcp_bind_to_netif
(
l_ip6
,
"ho0"
)
!=
ERR_OK
)
{
BLog
(
BLOG_ERROR
,
"tcp_bind_to_netif failed"
);
BLog
(
BLOG_ERROR
,
"tcp_bind_to_netif failed"
);
tcp_close
(
l_ip6
);
tcp_close
(
l_ip6
);
goto
fail
;
goto
fail
;
}
}
if
(
!
(
listener_ip6
=
tcp_listen
(
l_ip6
)))
{
if
(
!
(
listener_ip6
=
tcp_listen
(
l_ip6
)))
{
BLog
(
BLOG_ERROR
,
"tcp_listen failed"
);
BLog
(
BLOG_ERROR
,
"tcp_listen failed"
);
tcp_close
(
l_ip6
);
tcp_close
(
l_ip6
);
goto
fail
;
goto
fail
;
}
}
tcp_accept
(
listener_ip6
,
listener_accept_func
);
tcp_accept
(
listener_ip6
,
listener_accept_func
);
}
}
return
;
return
;
fail:
fail:
if
(
!
quitting
)
{
if
(
!
quitting
)
{
terminate
();
terminate
();
...
@@ -1378,13 +1347,13 @@ fail:
...
@@ -1378,13 +1347,13 @@ fail:
void
tcp_timer_handler
(
void
*
unused
)
void
tcp_timer_handler
(
void
*
unused
)
{
{
ASSERT
(
!
quitting
)
ASSERT
(
!
quitting
)
BLog
(
BLOG_DEBUG
,
"TCP timer"
);
BLog
(
BLOG_DEBUG
,
"TCP timer"
);
// schedule next timer
// schedule next timer
// TODO: calculate timeout so we don't drift
// TODO: calculate timeout so we don't drift
BReactor_SetTimer
(
&
ss
,
&
tcp_timer
);
BReactor_SetTimer
(
&
ss
,
&
tcp_timer
);
tcp_tmr
();
tcp_tmr
();
return
;
return
;
}
}
...
@@ -1392,9 +1361,9 @@ void tcp_timer_handler (void *unused)
...
@@ -1392,9 +1361,9 @@ void tcp_timer_handler (void *unused)
void
device_error_handler
(
void
*
unused
)
void
device_error_handler
(
void
*
unused
)
{
{
ASSERT
(
!
quitting
)
ASSERT
(
!
quitting
)
BLog
(
BLOG_ERROR
,
"device error"
);
BLog
(
BLOG_ERROR
,
"device error"
);
terminate
();
terminate
();
return
;
return
;
}
}
...
@@ -1403,9 +1372,9 @@ void device_read_handler_send (void *unused, uint8_t *data, int data_len)
...
@@ -1403,9 +1372,9 @@ void device_read_handler_send (void *unused, uint8_t *data, int data_len)
{
{
ASSERT
(
!
quitting
)
ASSERT
(
!
quitting
)
ASSERT
(
data_len
>=
0
)
ASSERT
(
data_len
>=
0
)
BLog
(
BLOG_DEBUG
,
"device: received packet"
);
BLog
(
BLOG_DEBUG
,
"device: received packet"
);
// accept packet
// accept packet
PacketPassInterface_Done
(
&
device_read_interface
);
PacketPassInterface_Done
(
&
device_read_interface
);
...
@@ -1415,12 +1384,12 @@ void device_read_handler_send (void *unused, uint8_t *data, int data_len)
...
@@ -1415,12 +1384,12 @@ void device_read_handler_send (void *unused, uint8_t *data, int data_len)
return
;
return
;
}
}
#endif
#endif
// process UDP directly
// process UDP directly
if
(
process_device_udp_packet
(
data
,
data_len
))
{
if
(
process_device_udp_packet
(
data
,
data_len
))
{
return
;
return
;
}
}
// obtain pbuf
// obtain pbuf
if
(
data_len
>
UINT16_MAX
)
{
if
(
data_len
>
UINT16_MAX
)
{
BLog
(
BLOG_WARNING
,
"device read: packet too large"
);
BLog
(
BLOG_WARNING
,
"device read: packet too large"
);
...
@@ -1431,10 +1400,10 @@ void device_read_handler_send (void *unused, uint8_t *data, int data_len)
...
@@ -1431,10 +1400,10 @@ void device_read_handler_send (void *unused, uint8_t *data, int data_len)
BLog
(
BLOG_WARNING
,
"device read: pbuf_alloc failed"
);
BLog
(
BLOG_WARNING
,
"device read: pbuf_alloc failed"
);
return
;
return
;
}
}
// write packet to pbuf
// write packet to pbuf
ASSERT_FORCE
(
pbuf_take
(
p
,
data
,
data_len
)
==
ERR_OK
)
ASSERT_FORCE
(
pbuf_take
(
p
,
data
,
data_len
)
==
ERR_OK
)
// pass pbuf to input
// pass pbuf to input
if
(
netif
.
input
(
p
,
&
netif
)
!=
ERR_OK
)
{
if
(
netif
.
input
(
p
,
&
netif
)
!=
ERR_OK
)
{
BLog
(
BLOG_WARNING
,
"device read: input failed"
);
BLog
(
BLOG_WARNING
,
"device read: input failed"
);
...
@@ -1446,42 +1415,42 @@ void device_read_handler_send (void *unused, uint8_t *data, int data_len)
...
@@ -1446,42 +1415,42 @@ void device_read_handler_send (void *unused, uint8_t *data, int data_len)
int
process_device_dns_packet
(
uint8_t
*
data
,
int
data_len
)
int
process_device_dns_packet
(
uint8_t
*
data
,
int
data_len
)
{
{
ASSERT
(
data_len
>=
0
)
ASSERT
(
data_len
>=
0
)
// do nothing if we don't have dnsgw
// do nothing if we don't have dnsgw
if
(
!
options
.
dnsgw
)
{
if
(
!
options
.
dnsgw
)
{
goto
fail
;
goto
fail
;
}
}
static
int
init
=
0
;
static
int
init
=
0
;
int
to_dns
;
int
to_dns
;
int
from_dns
;
int
from_dns
;
int
packet_length
=
0
;
int
packet_length
=
0
;
uint8_t
ip_version
=
0
;
uint8_t
ip_version
=
0
;
if
(
data_len
>
0
)
{
if
(
data_len
>
0
)
{
ip_version
=
(
data
[
0
]
>>
4
);
ip_version
=
(
data
[
0
]
>>
4
);
}
}
switch
(
ip_version
)
{
switch
(
ip_version
)
{
case
4
:
{
case
4
:
{
// ignore non-UDP packets
// ignore non-UDP packets
if
(
data_len
<
sizeof
(
struct
ipv4_header
)
||
data
[
offsetof
(
struct
ipv4_header
,
protocol
)]
!=
IPV4_PROTOCOL_UDP
)
{
if
(
data_len
<
sizeof
(
struct
ipv4_header
)
||
data
[
offsetof
(
struct
ipv4_header
,
protocol
)]
!=
IPV4_PROTOCOL_UDP
)
{
goto
fail
;
goto
fail
;
}
}
// parse IPv4 header
// parse IPv4 header
struct
ipv4_header
ipv4_header
;
struct
ipv4_header
ipv4_header
;
if
(
!
ipv4_check
(
data
,
data_len
,
&
ipv4_header
,
&
data
,
&
data_len
))
{
if
(
!
ipv4_check
(
data
,
data_len
,
&
ipv4_header
,
&
data
,
&
data_len
))
{
goto
fail
;
goto
fail
;
}
}
// parse UDP
// parse UDP
struct
udp_header
udp_header
;
struct
udp_header
udp_header
;
if
(
!
udp_check
(
data
,
data_len
,
&
udp_header
,
&
data
,
&
data_len
))
{
if
(
!
udp_check
(
data
,
data_len
,
&
udp_header
,
&
data
,
&
data_len
))
{
goto
fail
;
goto
fail
;
}
}
// verify UDP checksum
// verify UDP checksum
uint16_t
checksum_in_packet
=
udp_header
.
checksum
;
uint16_t
checksum_in_packet
=
udp_header
.
checksum
;
udp_header
.
checksum
=
0
;
udp_header
.
checksum
=
0
;
...
@@ -1550,7 +1519,7 @@ int process_device_dns_packet (uint8_t *data, int data_len)
...
@@ -1550,7 +1519,7 @@ int process_device_dns_packet (uint8_t *data, int data_len)
goto
fail
;
goto
fail
;
}
}
}
}
// update IPv4 header's checksum
// update IPv4 header's checksum
ipv4_header
.
checksum
=
hton16
(
0
);
ipv4_header
.
checksum
=
hton16
(
0
);
ipv4_header
.
checksum
=
ipv4_checksum
(
&
ipv4_header
,
NULL
,
0
);
ipv4_header
.
checksum
=
ipv4_checksum
(
&
ipv4_header
,
NULL
,
0
);
...
@@ -1567,22 +1536,22 @@ int process_device_dns_packet (uint8_t *data, int data_len)
...
@@ -1567,22 +1536,22 @@ int process_device_dns_packet (uint8_t *data, int data_len)
packet_length
=
sizeof
(
ipv4_header
)
+
sizeof
(
udp_header
)
+
data_len
;
packet_length
=
sizeof
(
ipv4_header
)
+
sizeof
(
udp_header
)
+
data_len
;
}
break
;
}
break
;
case
6
:
{
case
6
:
{
// TODO: support IPv6 DNS Gateway
// TODO: support IPv6 DNS Gateway
goto
fail
;
goto
fail
;
}
break
;
}
break
;
default:
{
default:
{
goto
fail
;
goto
fail
;
}
break
;
}
break
;
}
}
// submit packet
// submit packet
BTap_Send
(
&
device
,
device_write_buf
,
packet_length
);
BTap_Send
(
&
device
,
device_write_buf
,
packet_length
);
return
1
;
return
1
;
fail:
fail:
return
0
;
return
0
;
}
}
...
@@ -1591,40 +1560,40 @@ fail:
...
@@ -1591,40 +1560,40 @@ fail:
int
process_device_udp_packet
(
uint8_t
*
data
,
int
data_len
)
int
process_device_udp_packet
(
uint8_t
*
data
,
int
data_len
)
{
{
ASSERT
(
data_len
>=
0
)
ASSERT
(
data_len
>=
0
)
// do nothing if we don't have udpgw
// do nothing if we don't have udpgw
if
(
!
options
.
udpgw_remote_server_addr
)
{
if
(
!
options
.
udpgw_remote_server_addr
)
{
goto
fail
;
goto
fail
;
}
}
BAddr
local_addr
;
BAddr
local_addr
;
BAddr
remote_addr
;
BAddr
remote_addr
;
int
is_dns
;
int
is_dns
;
uint8_t
ip_version
=
0
;
uint8_t
ip_version
=
0
;
if
(
data_len
>
0
)
{
if
(
data_len
>
0
)
{
ip_version
=
(
data
[
0
]
>>
4
);
ip_version
=
(
data
[
0
]
>>
4
);
}
}
switch
(
ip_version
)
{
switch
(
ip_version
)
{
case
4
:
{
case
4
:
{
// ignore non-UDP packets
// ignore non-UDP packets
if
(
data_len
<
sizeof
(
struct
ipv4_header
)
||
data
[
offsetof
(
struct
ipv4_header
,
protocol
)]
!=
IPV4_PROTOCOL_UDP
)
{
if
(
data_len
<
sizeof
(
struct
ipv4_header
)
||
data
[
offsetof
(
struct
ipv4_header
,
protocol
)]
!=
IPV4_PROTOCOL_UDP
)
{
goto
fail
;
goto
fail
;
}
}
// parse IPv4 header
// parse IPv4 header
struct
ipv4_header
ipv4_header
;
struct
ipv4_header
ipv4_header
;
if
(
!
ipv4_check
(
data
,
data_len
,
&
ipv4_header
,
&
data
,
&
data_len
))
{
if
(
!
ipv4_check
(
data
,
data_len
,
&
ipv4_header
,
&
data
,
&
data_len
))
{
goto
fail
;
goto
fail
;
}
}
// parse UDP
// parse UDP
struct
udp_header
udp_header
;
struct
udp_header
udp_header
;
if
(
!
udp_check
(
data
,
data_len
,
&
udp_header
,
&
data
,
&
data_len
))
{
if
(
!
udp_check
(
data
,
data_len
,
&
udp_header
,
&
data
,
&
data_len
))
{
goto
fail
;
goto
fail
;
}
}
// verify UDP checksum
// verify UDP checksum
uint16_t
checksum_in_packet
=
udp_header
.
checksum
;
uint16_t
checksum_in_packet
=
udp_header
.
checksum
;
udp_header
.
checksum
=
0
;
udp_header
.
checksum
=
0
;
...
@@ -1632,43 +1601,43 @@ int process_device_udp_packet (uint8_t *data, int data_len)
...
@@ -1632,43 +1601,43 @@ int process_device_udp_packet (uint8_t *data, int data_len)
if
(
checksum_in_packet
!=
checksum_computed
)
{
if
(
checksum_in_packet
!=
checksum_computed
)
{
goto
fail
;
goto
fail
;
}
}
BLog
(
BLOG_INFO
,
"UDP: from device %d bytes"
,
data_len
);
BLog
(
BLOG_INFO
,
"UDP: from device %d bytes"
,
data_len
);
// construct addresses
// construct addresses
BAddr_InitIPv4
(
&
local_addr
,
ipv4_header
.
source_address
,
udp_header
.
source_port
);
BAddr_InitIPv4
(
&
local_addr
,
ipv4_header
.
source_address
,
udp_header
.
source_port
);
BAddr_InitIPv4
(
&
remote_addr
,
ipv4_header
.
destination_address
,
udp_header
.
dest_port
);
BAddr_InitIPv4
(
&
remote_addr
,
ipv4_header
.
destination_address
,
udp_header
.
dest_port
);
// if transparent DNS is enabled, any packet arriving at out netif
// if transparent DNS is enabled, any packet arriving at out netif
// address to port 53 is considered a DNS packet
// address to port 53 is considered a DNS packet
is_dns
=
(
options
.
udpgw_transparent_dns
&&
is_dns
=
(
options
.
udpgw_transparent_dns
&&
ipv4_header
.
destination_address
==
netif_ipaddr
.
ipv4
&&
ipv4_header
.
destination_address
==
netif_ipaddr
.
ipv4
&&
udp_header
.
dest_port
==
hton16
(
53
));
udp_header
.
dest_port
==
hton16
(
53
));
}
break
;
}
break
;
case
6
:
{
case
6
:
{
// ignore if IPv6 support is disabled
// ignore if IPv6 support is disabled
if
(
!
options
.
netif_ip6addr
)
{
if
(
!
options
.
netif_ip6addr
)
{
goto
fail
;
goto
fail
;
}
}
// ignore non-UDP packets
// ignore non-UDP packets
if
(
data_len
<
sizeof
(
struct
ipv6_header
)
||
data
[
offsetof
(
struct
ipv6_header
,
next_header
)]
!=
IPV6_NEXT_UDP
)
{
if
(
data_len
<
sizeof
(
struct
ipv6_header
)
||
data
[
offsetof
(
struct
ipv6_header
,
next_header
)]
!=
IPV6_NEXT_UDP
)
{
goto
fail
;
goto
fail
;
}
}
// parse IPv6 header
// parse IPv6 header
struct
ipv6_header
ipv6_header
;
struct
ipv6_header
ipv6_header
;
if
(
!
ipv6_check
(
data
,
data_len
,
&
ipv6_header
,
&
data
,
&
data_len
))
{
if
(
!
ipv6_check
(
data
,
data_len
,
&
ipv6_header
,
&
data
,
&
data_len
))
{
goto
fail
;
goto
fail
;
}
}
// parse UDP
// parse UDP
struct
udp_header
udp_header
;
struct
udp_header
udp_header
;
if
(
!
udp_check
(
data
,
data_len
,
&
udp_header
,
&
data
,
&
data_len
))
{
if
(
!
udp_check
(
data
,
data_len
,
&
udp_header
,
&
data
,
&
data_len
))
{
goto
fail
;
goto
fail
;
}
}
// verify UDP checksum
// verify UDP checksum
uint16_t
checksum_in_packet
=
udp_header
.
checksum
;
uint16_t
checksum_in_packet
=
udp_header
.
checksum
;
udp_header
.
checksum
=
0
;
udp_header
.
checksum
=
0
;
...
@@ -1676,33 +1645,33 @@ int process_device_udp_packet (uint8_t *data, int data_len)
...
@@ -1676,33 +1645,33 @@ int process_device_udp_packet (uint8_t *data, int data_len)
if
(
checksum_in_packet
!=
checksum_computed
)
{
if
(
checksum_in_packet
!=
checksum_computed
)
{
goto
fail
;
goto
fail
;
}
}
BLog
(
BLOG_INFO
,
"UDP/IPv6: from device %d bytes"
,
data_len
);
BLog
(
BLOG_INFO
,
"UDP/IPv6: from device %d bytes"
,
data_len
);
// construct addresses
// construct addresses
BAddr_InitIPv6
(
&
local_addr
,
ipv6_header
.
source_address
,
udp_header
.
source_port
);
BAddr_InitIPv6
(
&
local_addr
,
ipv6_header
.
source_address
,
udp_header
.
source_port
);
BAddr_InitIPv6
(
&
remote_addr
,
ipv6_header
.
destination_address
,
udp_header
.
dest_port
);
BAddr_InitIPv6
(
&
remote_addr
,
ipv6_header
.
destination_address
,
udp_header
.
dest_port
);
// TODO dns
// TODO dns
is_dns
=
0
;
is_dns
=
0
;
}
break
;
}
break
;
default:
{
default:
{
goto
fail
;
goto
fail
;
}
break
;
}
break
;
}
}
// check payload length
// check payload length
if
(
data_len
>
udp_mtu
)
{
if
(
data_len
>
udp_mtu
)
{
BLog
(
BLOG_ERROR
,
"packet is too large, cannot send to udpgw"
);
BLog
(
BLOG_ERROR
,
"packet is too large, cannot send to udpgw"
);
goto
fail
;
goto
fail
;
}
}
// submit packet to udpgw
// submit packet to udpgw
SocksUdpGwClient_SubmitPacket
(
&
udpgw_client
,
local_addr
,
remote_addr
,
is_dns
,
data
,
data_len
);
SocksUdpGwClient_SubmitPacket
(
&
udpgw_client
,
local_addr
,
remote_addr
,
is_dns
,
data
,
data_len
);
return
1
;
return
1
;
fail:
fail:
return
0
;
return
0
;
}
}
...
@@ -1710,12 +1679,12 @@ fail:
...
@@ -1710,12 +1679,12 @@ fail:
err_t
netif_init_func
(
struct
netif
*
netif
)
err_t
netif_init_func
(
struct
netif
*
netif
)
{
{
BLog
(
BLOG_DEBUG
,
"netif func init"
);
BLog
(
BLOG_DEBUG
,
"netif func init"
);
netif
->
name
[
0
]
=
'h'
;
netif
->
name
[
0
]
=
'h'
;
netif
->
name
[
1
]
=
'o'
;
netif
->
name
[
1
]
=
'o'
;
netif
->
output
=
netif_output_func
;
netif
->
output
=
netif_output_func
;
netif
->
output_ip6
=
netif_output_ip6_func
;
netif
->
output_ip6
=
netif_output_ip6_func
;
return
ERR_OK
;
return
ERR_OK
;
}
}
...
@@ -1732,20 +1701,20 @@ err_t netif_output_ip6_func (struct netif *netif, struct pbuf *p, ip6_addr_t *ip
...
@@ -1732,20 +1701,20 @@ err_t netif_output_ip6_func (struct netif *netif, struct pbuf *p, ip6_addr_t *ip
err_t
common_netif_output
(
struct
netif
*
netif
,
struct
pbuf
*
p
)
err_t
common_netif_output
(
struct
netif
*
netif
,
struct
pbuf
*
p
)
{
{
SYNC_DECL
SYNC_DECL
BLog
(
BLOG_DEBUG
,
"device write: send packet"
);
BLog
(
BLOG_DEBUG
,
"device write: send packet"
);
if
(
quitting
)
{
if
(
quitting
)
{
return
ERR_OK
;
return
ERR_OK
;
}
}
// if there is just one chunk, send it directly, else via buffer
// if there is just one chunk, send it directly, else via buffer
if
(
!
p
->
next
)
{
if
(
!
p
->
next
)
{
if
(
p
->
len
>
BTap_GetMTU
(
&
device
))
{
if
(
p
->
len
>
BTap_GetMTU
(
&
device
))
{
BLog
(
BLOG_WARNING
,
"netif func output: no space left"
);
BLog
(
BLOG_WARNING
,
"netif func output: no space left"
);
goto
out
;
goto
out
;
}
}
SYNC_FROMHERE
SYNC_FROMHERE
BTap_Send
(
&
device
,
(
uint8_t
*
)
p
->
payload
,
p
->
len
);
BTap_Send
(
&
device
,
(
uint8_t
*
)
p
->
payload
,
p
->
len
);
SYNC_COMMIT
SYNC_COMMIT
...
@@ -1759,12 +1728,12 @@ err_t common_netif_output (struct netif *netif, struct pbuf *p)
...
@@ -1759,12 +1728,12 @@ err_t common_netif_output (struct netif *netif, struct pbuf *p)
memcpy
(
device_write_buf
+
len
,
p
->
payload
,
p
->
len
);
memcpy
(
device_write_buf
+
len
,
p
->
payload
,
p
->
len
);
len
+=
p
->
len
;
len
+=
p
->
len
;
}
while
(
p
=
p
->
next
);
}
while
(
p
=
p
->
next
);
SYNC_FROMHERE
SYNC_FROMHERE
BTap_Send
(
&
device
,
device_write_buf
,
len
);
BTap_Send
(
&
device
,
device_write_buf
,
len
);
SYNC_COMMIT
SYNC_COMMIT
}
}
out:
out:
return
ERR_OK
;
return
ERR_OK
;
}
}
...
@@ -1775,7 +1744,7 @@ err_t netif_input_func (struct pbuf *p, struct netif *inp)
...
@@ -1775,7 +1744,7 @@ err_t netif_input_func (struct pbuf *p, struct netif *inp)
if
(
p
->
len
>
0
)
{
if
(
p
->
len
>
0
)
{
ip_version
=
(((
uint8_t
*
)
p
->
payload
)[
0
]
>>
4
);
ip_version
=
(((
uint8_t
*
)
p
->
payload
)[
0
]
>>
4
);
}
}
switch
(
ip_version
)
{
switch
(
ip_version
)
{
case
4
:
{
case
4
:
{
return
ip_input
(
p
,
inp
);
return
ip_input
(
p
,
inp
);
...
@@ -1786,7 +1755,7 @@ err_t netif_input_func (struct pbuf *p, struct netif *inp)
...
@@ -1786,7 +1755,7 @@ err_t netif_input_func (struct pbuf *p, struct netif *inp)
}
}
}
break
;
}
break
;
}
}
pbuf_free
(
p
);
pbuf_free
(
p
);
return
ERR_OK
;
return
ERR_OK
;
}
}
...
@@ -1797,7 +1766,7 @@ void client_logfunc (struct tcp_client *client)
...
@@ -1797,7 +1766,7 @@ void client_logfunc (struct tcp_client *client)
BAddr_Print
(
&
client
->
local_addr
,
local_addr_s
);
BAddr_Print
(
&
client
->
local_addr
,
local_addr_s
);
char
remote_addr_s
[
BADDR_MAX_PRINT_LEN
];
char
remote_addr_s
[
BADDR_MAX_PRINT_LEN
];
BAddr_Print
(
&
client
->
remote_addr
,
remote_addr_s
);
BAddr_Print
(
&
client
->
remote_addr
,
remote_addr_s
);
BLog_Append
(
"%05d (%s %s): "
,
num_clients
,
local_addr_s
,
remote_addr_s
);
BLog_Append
(
"%05d (%s %s): "
,
num_clients
,
local_addr_s
,
remote_addr_s
);
}
}
...
@@ -1812,11 +1781,11 @@ void client_log (struct tcp_client *client, int level, const char *fmt, ...)
...
@@ -1812,11 +1781,11 @@ void client_log (struct tcp_client *client, int level, const char *fmt, ...)
err_t
listener_accept_func
(
void
*
arg
,
struct
tcp_pcb
*
newpcb
,
err_t
err
)
err_t
listener_accept_func
(
void
*
arg
,
struct
tcp_pcb
*
newpcb
,
err_t
err
)
{
{
ASSERT
(
err
==
ERR_OK
)
ASSERT
(
err
==
ERR_OK
)
// signal accepted
// signal accepted
struct
tcp_pcb
*
this_listener
=
(
PCB_ISIPV6
(
newpcb
)
?
listener_ip6
:
listener
);
struct
tcp_pcb
*
this_listener
=
(
PCB_ISIPV6
(
newpcb
)
?
listener_ip6
:
listener
);
tcp_accepted
(
this_listener
);
tcp_accepted
(
this_listener
);
// allocate client structure
// allocate client structure
struct
tcp_client
*
client
=
(
struct
tcp_client
*
)
malloc
(
sizeof
(
*
client
));
struct
tcp_client
*
client
=
(
struct
tcp_client
*
)
malloc
(
sizeof
(
*
client
));
if
(
!
client
)
{
if
(
!
client
)
{
...
@@ -1824,20 +1793,20 @@ err_t listener_accept_func (void *arg, struct tcp_pcb *newpcb, err_t err)
...
@@ -1824,20 +1793,20 @@ err_t listener_accept_func (void *arg, struct tcp_pcb *newpcb, err_t err)
goto
fail0
;
goto
fail0
;
}
}
client
->
socks_username
=
NULL
;
client
->
socks_username
=
NULL
;
SYNC_DECL
SYNC_DECL
SYNC_FROMHERE
SYNC_FROMHERE
// read addresses
// read addresses
client
->
local_addr
=
baddr_from_lwip
(
PCB_ISIPV6
(
newpcb
),
&
newpcb
->
local_ip
,
newpcb
->
local_port
);
client
->
local_addr
=
baddr_from_lwip
(
PCB_ISIPV6
(
newpcb
),
&
newpcb
->
local_ip
,
newpcb
->
local_port
);
client
->
remote_addr
=
baddr_from_lwip
(
PCB_ISIPV6
(
newpcb
),
&
newpcb
->
remote_ip
,
newpcb
->
remote_port
);
client
->
remote_addr
=
baddr_from_lwip
(
PCB_ISIPV6
(
newpcb
),
&
newpcb
->
remote_ip
,
newpcb
->
remote_port
);
// get destination address
// get destination address
BAddr
addr
=
client
->
local_addr
;
BAddr
addr
=
client
->
local_addr
;
#ifdef OVERRIDE_DEST_ADDR
#ifdef OVERRIDE_DEST_ADDR
ASSERT_FORCE
(
BAddr_Parse2
(
&
addr
,
OVERRIDE_DEST_ADDR
,
NULL
,
0
,
1
))
ASSERT_FORCE
(
BAddr_Parse2
(
&
addr
,
OVERRIDE_DEST_ADDR
,
NULL
,
0
,
1
))
#endif
#endif
// add source address to username if requested
// add source address to username if requested
if
(
options
.
username
&&
options
.
append_source_to_username
)
{
if
(
options
.
username
&&
options
.
append_source_to_username
)
{
char
addr_str
[
BADDR_MAX_PRINT_LEN
];
char
addr_str
[
BADDR_MAX_PRINT_LEN
];
...
@@ -1849,56 +1818,56 @@ err_t listener_accept_func (void *arg, struct tcp_pcb *newpcb, err_t err)
...
@@ -1849,56 +1818,56 @@ err_t listener_accept_func (void *arg, struct tcp_pcb *newpcb, err_t err)
socks_auth_info
[
1
].
password
.
username
=
client
->
socks_username
;
socks_auth_info
[
1
].
password
.
username
=
client
->
socks_username
;
socks_auth_info
[
1
].
password
.
username_len
=
strlen
(
client
->
socks_username
);
socks_auth_info
[
1
].
password
.
username_len
=
strlen
(
client
->
socks_username
);
}
}
// init SOCKS
// init SOCKS
if
(
!
BSocksClient_Init
(
&
client
->
socks_client
,
socks_server_addr
,
socks_auth_info
,
socks_num_auth_info
,
if
(
!
BSocksClient_Init
(
&
client
->
socks_client
,
socks_server_addr
,
socks_auth_info
,
socks_num_auth_info
,
addr
,
(
BSocksClient_handler
)
client_socks_handler
,
client
,
&
ss
))
{
addr
,
(
BSocksClient_handler
)
client_socks_handler
,
client
,
&
ss
))
{
BLog
(
BLOG_ERROR
,
"listener accept: BSocksClient_Init failed"
);
BLog
(
BLOG_ERROR
,
"listener accept: BSocksClient_Init failed"
);
goto
fail1
;
goto
fail1
;
}
}
// init dead vars
// init dead vars
DEAD_INIT
(
client
->
dead
);
DEAD_INIT
(
client
->
dead
);
DEAD_INIT
(
client
->
dead_client
);
DEAD_INIT
(
client
->
dead_client
);
// add to linked list
// add to linked list
LinkedList1_Append
(
&
tcp_clients
,
&
client
->
list_node
);
LinkedList1_Append
(
&
tcp_clients
,
&
client
->
list_node
);
// increment counter
// increment counter
ASSERT
(
num_clients
>=
0
)
ASSERT
(
num_clients
>=
0
)
num_clients
++
;
num_clients
++
;
// set pcb
// set pcb
client
->
pcb
=
newpcb
;
client
->
pcb
=
newpcb
;
// set client not closed
// set client not closed
client
->
client_closed
=
0
;
client
->
client_closed
=
0
;
// setup handler argument
// setup handler argument
tcp_arg
(
client
->
pcb
,
client
);
tcp_arg
(
client
->
pcb
,
client
);
// setup handlers
// setup handlers
tcp_err
(
client
->
pcb
,
client_err_func
);
tcp_err
(
client
->
pcb
,
client_err_func
);
tcp_recv
(
client
->
pcb
,
client_recv_func
);
tcp_recv
(
client
->
pcb
,
client_recv_func
);
// setup buffer
// setup buffer
client
->
buf_used
=
0
;
client
->
buf_used
=
0
;
// set SOCKS not up, not closed
// set SOCKS not up, not closed
client
->
socks_up
=
0
;
client
->
socks_up
=
0
;
client
->
socks_closed
=
0
;
client
->
socks_closed
=
0
;
client_log
(
client
,
BLOG_INFO
,
"accepted"
);
client_log
(
client
,
BLOG_INFO
,
"accepted"
);
DEAD_ENTER
(
client
->
dead_client
)
DEAD_ENTER
(
client
->
dead_client
)
SYNC_COMMIT
SYNC_COMMIT
DEAD_LEAVE2
(
client
->
dead_client
)
DEAD_LEAVE2
(
client
->
dead_client
)
if
(
DEAD_KILLED
)
{
if
(
DEAD_KILLED
)
{
return
ERR_ABRT
;
return
ERR_ABRT
;
}
}
return
ERR_OK
;
return
ERR_OK
;
fail1:
fail1:
SYNC_BREAK
SYNC_BREAK
free
(
client
->
socks_username
);
free
(
client
->
socks_username
);
...
@@ -1910,15 +1879,15 @@ fail0:
...
@@ -1910,15 +1879,15 @@ fail0:
void
client_handle_freed_client
(
struct
tcp_client
*
client
)
void
client_handle_freed_client
(
struct
tcp_client
*
client
)
{
{
ASSERT
(
!
client
->
client_closed
)
ASSERT
(
!
client
->
client_closed
)
// pcb was taken care of by the caller
// pcb was taken care of by the caller
// kill client dead var
// kill client dead var
DEAD_KILL
(
client
->
dead_client
);
DEAD_KILL
(
client
->
dead_client
);
// set client closed
// set client closed
client
->
client_closed
=
1
;
client
->
client_closed
=
1
;
// if we have data to be sent to SOCKS and can send it, keep sending
// if we have data to be sent to SOCKS and can send it, keep sending
if
(
client
->
buf_used
>
0
&&
!
client
->
socks_closed
)
{
if
(
client
->
buf_used
>
0
&&
!
client
->
socks_closed
)
{
client_log
(
client
,
BLOG_INFO
,
"waiting untill buffered data is sent to SOCKS"
);
client_log
(
client
,
BLOG_INFO
,
"waiting untill buffered data is sent to SOCKS"
);
...
@@ -1934,41 +1903,41 @@ void client_handle_freed_client (struct tcp_client *client)
...
@@ -1934,41 +1903,41 @@ void client_handle_freed_client (struct tcp_client *client)
void
client_free_client
(
struct
tcp_client
*
client
)
void
client_free_client
(
struct
tcp_client
*
client
)
{
{
ASSERT
(
!
client
->
client_closed
)
ASSERT
(
!
client
->
client_closed
)
// remove callbacks
// remove callbacks
tcp_err
(
client
->
pcb
,
NULL
);
tcp_err
(
client
->
pcb
,
NULL
);
tcp_recv
(
client
->
pcb
,
NULL
);
tcp_recv
(
client
->
pcb
,
NULL
);
tcp_sent
(
client
->
pcb
,
NULL
);
tcp_sent
(
client
->
pcb
,
NULL
);
// free pcb
// free pcb
err_t
err
=
tcp_close
(
client
->
pcb
);
err_t
err
=
tcp_close
(
client
->
pcb
);
if
(
err
!=
ERR_OK
)
{
if
(
err
!=
ERR_OK
)
{
client_log
(
client
,
BLOG_ERROR
,
"tcp_close failed (%d)"
,
err
);
client_log
(
client
,
BLOG_ERROR
,
"tcp_close failed (%d)"
,
err
);
tcp_abort
(
client
->
pcb
);
tcp_abort
(
client
->
pcb
);
}
}
client_handle_freed_client
(
client
);
client_handle_freed_client
(
client
);
}
}
void
client_abort_client
(
struct
tcp_client
*
client
)
void
client_abort_client
(
struct
tcp_client
*
client
)
{
{
ASSERT
(
!
client
->
client_closed
)
ASSERT
(
!
client
->
client_closed
)
// remove callbacks
// remove callbacks
tcp_err
(
client
->
pcb
,
NULL
);
tcp_err
(
client
->
pcb
,
NULL
);
tcp_recv
(
client
->
pcb
,
NULL
);
tcp_recv
(
client
->
pcb
,
NULL
);
tcp_sent
(
client
->
pcb
,
NULL
);
tcp_sent
(
client
->
pcb
,
NULL
);
// free pcb
// free pcb
tcp_abort
(
client
->
pcb
);
tcp_abort
(
client
->
pcb
);
client_handle_freed_client
(
client
);
client_handle_freed_client
(
client
);
}
}
void
client_free_socks
(
struct
tcp_client
*
client
)
void
client_free_socks
(
struct
tcp_client
*
client
)
{
{
ASSERT
(
!
client
->
socks_closed
)
ASSERT
(
!
client
->
socks_closed
)
// stop sending to SOCKS
// stop sending to SOCKS
if
(
client
->
socks_up
)
{
if
(
client
->
socks_up
)
{
// stop receiving from client
// stop receiving from client
...
@@ -1976,13 +1945,13 @@ void client_free_socks (struct tcp_client *client)
...
@@ -1976,13 +1945,13 @@ void client_free_socks (struct tcp_client *client)
tcp_recv
(
client
->
pcb
,
NULL
);
tcp_recv
(
client
->
pcb
,
NULL
);
}
}
}
}
// free SOCKS
// free SOCKS
BSocksClient_Free
(
&
client
->
socks_client
);
BSocksClient_Free
(
&
client
->
socks_client
);
// set SOCKS closed
// set SOCKS closed
client
->
socks_closed
=
1
;
client
->
socks_closed
=
1
;
// if we have data to be sent to the client and we can send it, keep sending
// if we have data to be sent to the client and we can send it, keep sending
if
(
client
->
socks_up
&&
(
client
->
socks_recv_buf_used
>=
0
||
client
->
socks_recv_tcp_pending
>
0
)
&&
!
client
->
client_closed
)
{
if
(
client
->
socks_up
&&
(
client
->
socks_recv_buf_used
>=
0
||
client
->
socks_recv_tcp_pending
>
0
)
&&
!
client
->
client_closed
)
{
client_log
(
client
,
BLOG_INFO
,
"waiting until buffered data is sent to client"
);
client_log
(
client
,
BLOG_INFO
,
"waiting until buffered data is sent to client"
);
...
@@ -2003,26 +1972,26 @@ void client_murder (struct tcp_client *client)
...
@@ -2003,26 +1972,26 @@ void client_murder (struct tcp_client *client)
tcp_err
(
client
->
pcb
,
NULL
);
tcp_err
(
client
->
pcb
,
NULL
);
tcp_recv
(
client
->
pcb
,
NULL
);
tcp_recv
(
client
->
pcb
,
NULL
);
tcp_sent
(
client
->
pcb
,
NULL
);
tcp_sent
(
client
->
pcb
,
NULL
);
// abort
// abort
tcp_abort
(
client
->
pcb
);
tcp_abort
(
client
->
pcb
);
// kill client dead var
// kill client dead var
DEAD_KILL
(
client
->
dead_client
);
DEAD_KILL
(
client
->
dead_client
);
// set client closed
// set client closed
client
->
client_closed
=
1
;
client
->
client_closed
=
1
;
}
}
// free SOCKS
// free SOCKS
if
(
!
client
->
socks_closed
)
{
if
(
!
client
->
socks_closed
)
{
// free SOCKS
// free SOCKS
BSocksClient_Free
(
&
client
->
socks_client
);
BSocksClient_Free
(
&
client
->
socks_client
);
// set SOCKS closed
// set SOCKS closed
client
->
socks_closed
=
1
;
client
->
socks_closed
=
1
;
}
}
// dealloc entry
// dealloc entry
client_dealloc
(
client
);
client_dealloc
(
client
);
}
}
...
@@ -2031,17 +2000,17 @@ void client_dealloc (struct tcp_client *client)
...
@@ -2031,17 +2000,17 @@ void client_dealloc (struct tcp_client *client)
{
{
ASSERT
(
client
->
client_closed
)
ASSERT
(
client
->
client_closed
)
ASSERT
(
client
->
socks_closed
)
ASSERT
(
client
->
socks_closed
)
// decrement counter
// decrement counter
ASSERT
(
num_clients
>
0
)
ASSERT
(
num_clients
>
0
)
num_clients
--
;
num_clients
--
;
// remove client entry
// remove client entry
LinkedList1_Remove
(
&
tcp_clients
,
&
client
->
list_node
);
LinkedList1_Remove
(
&
tcp_clients
,
&
client
->
list_node
);
// kill dead var
// kill dead var
DEAD_KILL
(
client
->
dead
);
DEAD_KILL
(
client
->
dead
);
// free memory
// free memory
free
(
client
->
socks_username
);
free
(
client
->
socks_username
);
free
(
client
);
free
(
client
);
...
@@ -2051,9 +2020,9 @@ void client_err_func (void *arg, err_t err)
...
@@ -2051,9 +2020,9 @@ void client_err_func (void *arg, err_t err)
{
{
struct
tcp_client
*
client
=
(
struct
tcp_client
*
)
arg
;
struct
tcp_client
*
client
=
(
struct
tcp_client
*
)
arg
;
ASSERT
(
!
client
->
client_closed
)
ASSERT
(
!
client
->
client_closed
)
client_log
(
client
,
BLOG_INFO
,
"client error (%d)"
,
(
int
)
err
);
client_log
(
client
,
BLOG_INFO
,
"client error (%d)"
,
(
int
)
err
);
// the pcb was taken care of by the caller
// the pcb was taken care of by the caller
client_handle_freed_client
(
client
);
client_handle_freed_client
(
client
);
}
}
...
@@ -2064,29 +2033,29 @@ err_t client_recv_func (void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t e
...
@@ -2064,29 +2033,29 @@ err_t client_recv_func (void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t e
ASSERT
(
!
client
->
client_closed
)
ASSERT
(
!
client
->
client_closed
)
ASSERT
(
err
==
ERR_OK
)
// checked in lwIP source. Otherwise, I've no idea what should
ASSERT
(
err
==
ERR_OK
)
// checked in lwIP source. Otherwise, I've no idea what should
// be done with the pbuf in case of an error.
// be done with the pbuf in case of an error.
if
(
!
p
)
{
if
(
!
p
)
{
client_log
(
client
,
BLOG_INFO
,
"client closed"
);
client_log
(
client
,
BLOG_INFO
,
"client closed"
);
client_free_client
(
client
);
client_free_client
(
client
);
return
ERR_ABRT
;
return
ERR_ABRT
;
}
}
ASSERT
(
p
->
tot_len
>
0
)
ASSERT
(
p
->
tot_len
>
0
)
// check if we have enough buffer
// check if we have enough buffer
if
(
p
->
tot_len
>
sizeof
(
client
->
buf
)
-
client
->
buf_used
)
{
if
(
p
->
tot_len
>
sizeof
(
client
->
buf
)
-
client
->
buf_used
)
{
client_log
(
client
,
BLOG_ERROR
,
"no buffer for data !?!"
);
client_log
(
client
,
BLOG_ERROR
,
"no buffer for data !?!"
);
return
ERR_MEM
;
return
ERR_MEM
;
}
}
// copy data to buffer
// copy data to buffer
ASSERT_EXECUTE
(
pbuf_copy_partial
(
p
,
client
->
buf
+
client
->
buf_used
,
p
->
tot_len
,
0
)
==
p
->
tot_len
)
ASSERT_EXECUTE
(
pbuf_copy_partial
(
p
,
client
->
buf
+
client
->
buf_used
,
p
->
tot_len
,
0
)
==
p
->
tot_len
)
client
->
buf_used
+=
p
->
tot_len
;
client
->
buf_used
+=
p
->
tot_len
;
// if there was nothing in the buffer before, and SOCKS is up, start send data
// if there was nothing in the buffer before, and SOCKS is up, start send data
if
(
client
->
buf_used
==
p
->
tot_len
&&
client
->
socks_up
)
{
if
(
client
->
buf_used
==
p
->
tot_len
&&
client
->
socks_up
)
{
ASSERT
(
!
client
->
socks_closed
)
// this callback is removed when SOCKS is closed
ASSERT
(
!
client
->
socks_closed
)
// this callback is removed when SOCKS is closed
SYNC_DECL
SYNC_DECL
SYNC_FROMHERE
SYNC_FROMHERE
client_send_to_socks
(
client
);
client_send_to_socks
(
client
);
...
@@ -2097,33 +2066,33 @@ err_t client_recv_func (void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t e
...
@@ -2097,33 +2066,33 @@ err_t client_recv_func (void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t e
return
ERR_ABRT
;
return
ERR_ABRT
;
}
}
}
}
// free pbuff
// free pbuff
pbuf_free
(
p
);
pbuf_free
(
p
);
return
ERR_OK
;
return
ERR_OK
;
}
}
void
client_socks_handler
(
struct
tcp_client
*
client
,
int
event
)
void
client_socks_handler
(
struct
tcp_client
*
client
,
int
event
)
{
{
ASSERT
(
!
client
->
socks_closed
)
ASSERT
(
!
client
->
socks_closed
)
switch
(
event
)
{
switch
(
event
)
{
case
BSOCKSCLIENT_EVENT_ERROR
:
{
case
BSOCKSCLIENT_EVENT_ERROR
:
{
client_log
(
client
,
BLOG_INFO
,
"SOCKS error"
);
client_log
(
client
,
BLOG_INFO
,
"SOCKS error"
);
client_free_socks
(
client
);
client_free_socks
(
client
);
}
break
;
}
break
;
case
BSOCKSCLIENT_EVENT_UP
:
{
case
BSOCKSCLIENT_EVENT_UP
:
{
ASSERT
(
!
client
->
socks_up
)
ASSERT
(
!
client
->
socks_up
)
client_log
(
client
,
BLOG_INFO
,
"SOCKS up"
);
client_log
(
client
,
BLOG_INFO
,
"SOCKS up"
);
// init sending
// init sending
client
->
socks_send_if
=
BSocksClient_GetSendInterface
(
&
client
->
socks_client
);
client
->
socks_send_if
=
BSocksClient_GetSendInterface
(
&
client
->
socks_client
);
StreamPassInterface_Sender_Init
(
client
->
socks_send_if
,
(
StreamPassInterface_handler_done
)
client_socks_send_handler_done
,
client
);
StreamPassInterface_Sender_Init
(
client
->
socks_send_if
,
(
StreamPassInterface_handler_done
)
client_socks_send_handler_done
,
client
);
// init receiving
// init receiving
client
->
socks_recv_if
=
BSocksClient_GetRecvInterface
(
&
client
->
socks_client
);
client
->
socks_recv_if
=
BSocksClient_GetRecvInterface
(
&
client
->
socks_client
);
StreamRecvInterface_Receiver_Init
(
client
->
socks_recv_if
,
(
StreamRecvInterface_handler_done
)
client_socks_recv_handler_done
,
client
);
StreamRecvInterface_Receiver_Init
(
client
->
socks_recv_if
,
(
StreamRecvInterface_handler_done
)
client_socks_recv_handler_done
,
client
);
...
@@ -2132,29 +2101,29 @@ void client_socks_handler (struct tcp_client *client, int event)
...
@@ -2132,29 +2101,29 @@ void client_socks_handler (struct tcp_client *client, int event)
if
(
!
client
->
client_closed
)
{
if
(
!
client
->
client_closed
)
{
tcp_sent
(
client
->
pcb
,
client_sent_func
);
tcp_sent
(
client
->
pcb
,
client_sent_func
);
}
}
// set up
// set up
client
->
socks_up
=
1
;
client
->
socks_up
=
1
;
// start sending data if there is any
// start sending data if there is any
if
(
client
->
buf_used
>
0
)
{
if
(
client
->
buf_used
>
0
)
{
client_send_to_socks
(
client
);
client_send_to_socks
(
client
);
}
}
// start receiving data if client is still up
// start receiving data if client is still up
if
(
!
client
->
client_closed
)
{
if
(
!
client
->
client_closed
)
{
client_socks_recv_initiate
(
client
);
client_socks_recv_initiate
(
client
);
}
}
}
break
;
}
break
;
case
BSOCKSCLIENT_EVENT_ERROR_CLOSED
:
{
case
BSOCKSCLIENT_EVENT_ERROR_CLOSED
:
{
ASSERT
(
client
->
socks_up
)
ASSERT
(
client
->
socks_up
)
client_log
(
client
,
BLOG_INFO
,
"SOCKS closed"
);
client_log
(
client
,
BLOG_INFO
,
"SOCKS closed"
);
client_free_socks
(
client
);
client_free_socks
(
client
);
}
break
;
}
break
;
default:
default:
ASSERT
(
0
);
ASSERT
(
0
);
}
}
...
@@ -2165,7 +2134,7 @@ void client_send_to_socks (struct tcp_client *client)
...
@@ -2165,7 +2134,7 @@ void client_send_to_socks (struct tcp_client *client)
ASSERT
(
!
client
->
socks_closed
)
ASSERT
(
!
client
->
socks_closed
)
ASSERT
(
client
->
socks_up
)
ASSERT
(
client
->
socks_up
)
ASSERT
(
client
->
buf_used
>
0
)
ASSERT
(
client
->
buf_used
>
0
)
// schedule sending
// schedule sending
StreamPassInterface_Sender_Send
(
client
->
socks_send_if
,
client
->
buf
,
client
->
buf_used
);
StreamPassInterface_Sender_Send
(
client
->
socks_send_if
,
client
->
buf
,
client
->
buf_used
);
}
}
...
@@ -2177,16 +2146,16 @@ void client_socks_send_handler_done (struct tcp_client *client, int data_len)
...
@@ -2177,16 +2146,16 @@ void client_socks_send_handler_done (struct tcp_client *client, int data_len)
ASSERT
(
client
->
buf_used
>
0
)
ASSERT
(
client
->
buf_used
>
0
)
ASSERT
(
data_len
>
0
)
ASSERT
(
data_len
>
0
)
ASSERT
(
data_len
<=
client
->
buf_used
)
ASSERT
(
data_len
<=
client
->
buf_used
)
// remove sent data from buffer
// remove sent data from buffer
memmove
(
client
->
buf
,
client
->
buf
+
data_len
,
client
->
buf_used
-
data_len
);
memmove
(
client
->
buf
,
client
->
buf
+
data_len
,
client
->
buf_used
-
data_len
);
client
->
buf_used
-=
data_len
;
client
->
buf_used
-=
data_len
;
if
(
!
client
->
client_closed
)
{
if
(
!
client
->
client_closed
)
{
// confirm sent data
// confirm sent data
tcp_recved
(
client
->
pcb
,
data_len
);
tcp_recved
(
client
->
pcb
,
data_len
);
}
}
if
(
client
->
buf_used
>
0
)
{
if
(
client
->
buf_used
>
0
)
{
// send any further data
// send any further data
StreamPassInterface_Sender_Send
(
client
->
socks_send_if
,
client
->
buf
,
client
->
buf_used
);
StreamPassInterface_Sender_Send
(
client
->
socks_send_if
,
client
->
buf
,
client
->
buf_used
);
...
@@ -2194,7 +2163,7 @@ void client_socks_send_handler_done (struct tcp_client *client, int data_len)
...
@@ -2194,7 +2163,7 @@ void client_socks_send_handler_done (struct tcp_client *client, int data_len)
else
if
(
client
->
client_closed
)
{
else
if
(
client
->
client_closed
)
{
// client was closed we've sent everything we had buffered; we're done with it
// client was closed we've sent everything we had buffered; we're done with it
client_log
(
client
,
BLOG_INFO
,
"removing after client went down"
);
client_log
(
client
,
BLOG_INFO
,
"removing after client went down"
);
client_free_socks
(
client
);
client_free_socks
(
client
);
}
}
}
}
...
@@ -2205,7 +2174,7 @@ void client_socks_recv_initiate (struct tcp_client *client)
...
@@ -2205,7 +2174,7 @@ void client_socks_recv_initiate (struct tcp_client *client)
ASSERT
(
!
client
->
socks_closed
)
ASSERT
(
!
client
->
socks_closed
)
ASSERT
(
client
->
socks_up
)
ASSERT
(
client
->
socks_up
)
ASSERT
(
client
->
socks_recv_buf_used
==
-
1
)
ASSERT
(
client
->
socks_recv_buf_used
==
-
1
)
StreamRecvInterface_Receiver_Recv
(
client
->
socks_recv_if
,
client
->
socks_recv_buf
,
sizeof
(
client
->
socks_recv_buf
));
StreamRecvInterface_Receiver_Recv
(
client
->
socks_recv_if
,
client
->
socks_recv_buf
,
sizeof
(
client
->
socks_recv_buf
));
}
}
...
@@ -2216,22 +2185,22 @@ void client_socks_recv_handler_done (struct tcp_client *client, int data_len)
...
@@ -2216,22 +2185,22 @@ void client_socks_recv_handler_done (struct tcp_client *client, int data_len)
ASSERT
(
!
client
->
socks_closed
)
ASSERT
(
!
client
->
socks_closed
)
ASSERT
(
client
->
socks_up
)
ASSERT
(
client
->
socks_up
)
ASSERT
(
client
->
socks_recv_buf_used
==
-
1
)
ASSERT
(
client
->
socks_recv_buf_used
==
-
1
)
// if client was closed, stop receiving
// if client was closed, stop receiving
if
(
client
->
client_closed
)
{
if
(
client
->
client_closed
)
{
return
;
return
;
}
}
// set amount of data in buffer
// set amount of data in buffer
client
->
socks_recv_buf_used
=
data_len
;
client
->
socks_recv_buf_used
=
data_len
;
client
->
socks_recv_buf_sent
=
0
;
client
->
socks_recv_buf_sent
=
0
;
client
->
socks_recv_waiting
=
0
;
client
->
socks_recv_waiting
=
0
;
// send to client
// send to client
if
(
client_socks_recv_send_out
(
client
)
<
0
)
{
if
(
client_socks_recv_send_out
(
client
)
<
0
)
{
return
;
return
;
}
}
// continue receiving if needed
// continue receiving if needed
if
(
client
->
socks_recv_buf_used
==
-
1
)
{
if
(
client
->
socks_recv_buf_used
==
-
1
)
{
client_socks_recv_initiate
(
client
);
client_socks_recv_initiate
(
client
);
...
@@ -2245,89 +2214,89 @@ int client_socks_recv_send_out (struct tcp_client *client)
...
@@ -2245,89 +2214,89 @@ int client_socks_recv_send_out (struct tcp_client *client)
ASSERT
(
client
->
socks_recv_buf_used
>
0
)
ASSERT
(
client
->
socks_recv_buf_used
>
0
)
ASSERT
(
client
->
socks_recv_buf_sent
<
client
->
socks_recv_buf_used
)
ASSERT
(
client
->
socks_recv_buf_sent
<
client
->
socks_recv_buf_used
)
ASSERT
(
!
client
->
socks_recv_waiting
)
ASSERT
(
!
client
->
socks_recv_waiting
)
// return value -1 means tcp_abort() was done,
// return value -1 means tcp_abort() was done,
// 0 means it wasn't and the client (pcb) is still up
// 0 means it wasn't and the client (pcb) is still up
do
{
do
{
int
to_write
=
bmin_int
(
client
->
socks_recv_buf_used
-
client
->
socks_recv_buf_sent
,
tcp_sndbuf
(
client
->
pcb
));
int
to_write
=
bmin_int
(
client
->
socks_recv_buf_used
-
client
->
socks_recv_buf_sent
,
tcp_sndbuf
(
client
->
pcb
));
if
(
to_write
==
0
)
{
if
(
to_write
==
0
)
{
break
;
break
;
}
}
err_t
err
=
tcp_write
(
client
->
pcb
,
client
->
socks_recv_buf
+
client
->
socks_recv_buf_sent
,
to_write
,
TCP_WRITE_FLAG_COPY
);
err_t
err
=
tcp_write
(
client
->
pcb
,
client
->
socks_recv_buf
+
client
->
socks_recv_buf_sent
,
to_write
,
TCP_WRITE_FLAG_COPY
);
if
(
err
!=
ERR_OK
)
{
if
(
err
!=
ERR_OK
)
{
if
(
err
==
ERR_MEM
)
{
if
(
err
==
ERR_MEM
)
{
break
;
break
;
}
}
client_log
(
client
,
BLOG_INFO
,
"tcp_write failed (%d)"
,
(
int
)
err
);
client_log
(
client
,
BLOG_INFO
,
"tcp_write failed (%d)"
,
(
int
)
err
);
client_abort_client
(
client
);
client_abort_client
(
client
);
return
-
1
;
return
-
1
;
}
}
client
->
socks_recv_buf_sent
+=
to_write
;
client
->
socks_recv_buf_sent
+=
to_write
;
client
->
socks_recv_tcp_pending
+=
to_write
;
client
->
socks_recv_tcp_pending
+=
to_write
;
}
while
(
client
->
socks_recv_buf_sent
<
client
->
socks_recv_buf_used
);
}
while
(
client
->
socks_recv_buf_sent
<
client
->
socks_recv_buf_used
);
// start sending now
// start sending now
err_t
err
=
tcp_output
(
client
->
pcb
);
err_t
err
=
tcp_output
(
client
->
pcb
);
if
(
err
!=
ERR_OK
)
{
if
(
err
!=
ERR_OK
)
{
client_log
(
client
,
BLOG_INFO
,
"tcp_output failed (%d)"
,
(
int
)
err
);
client_log
(
client
,
BLOG_INFO
,
"tcp_output failed (%d)"
,
(
int
)
err
);
client_abort_client
(
client
);
client_abort_client
(
client
);
return
-
1
;
return
-
1
;
}
}
// more data to queue?
// more data to queue?
if
(
client
->
socks_recv_buf_sent
<
client
->
socks_recv_buf_used
)
{
if
(
client
->
socks_recv_buf_sent
<
client
->
socks_recv_buf_used
)
{
if
(
client
->
socks_recv_tcp_pending
==
0
)
{
if
(
client
->
socks_recv_tcp_pending
==
0
)
{
client_log
(
client
,
BLOG_ERROR
,
"can't queue data, but all data was confirmed !?!"
);
client_log
(
client
,
BLOG_ERROR
,
"can't queue data, but all data was confirmed !?!"
);
client_abort_client
(
client
);
client_abort_client
(
client
);
return
-
1
;
return
-
1
;
}
}
// set waiting, continue in client_sent_func
// set waiting, continue in client_sent_func
client
->
socks_recv_waiting
=
1
;
client
->
socks_recv_waiting
=
1
;
return
0
;
return
0
;
}
}
// everything was queued
// everything was queued
client
->
socks_recv_buf_used
=
-
1
;
client
->
socks_recv_buf_used
=
-
1
;
return
0
;
return
0
;
}
}
err_t
client_sent_func
(
void
*
arg
,
struct
tcp_pcb
*
tpcb
,
u16_t
len
)
err_t
client_sent_func
(
void
*
arg
,
struct
tcp_pcb
*
tpcb
,
u16_t
len
)
{
{
struct
tcp_client
*
client
=
(
struct
tcp_client
*
)
arg
;
struct
tcp_client
*
client
=
(
struct
tcp_client
*
)
arg
;
ASSERT
(
!
client
->
client_closed
)
ASSERT
(
!
client
->
client_closed
)
ASSERT
(
client
->
socks_up
)
ASSERT
(
client
->
socks_up
)
ASSERT
(
len
>
0
)
ASSERT
(
len
>
0
)
ASSERT
(
len
<=
client
->
socks_recv_tcp_pending
)
ASSERT
(
len
<=
client
->
socks_recv_tcp_pending
)
// decrement pending
// decrement pending
client
->
socks_recv_tcp_pending
-=
len
;
client
->
socks_recv_tcp_pending
-=
len
;
// continue queuing
// continue queuing
if
(
client
->
socks_recv_buf_used
>
0
)
{
if
(
client
->
socks_recv_buf_used
>
0
)
{
ASSERT
(
client
->
socks_recv_waiting
)
ASSERT
(
client
->
socks_recv_waiting
)
ASSERT
(
client
->
socks_recv_buf_sent
<
client
->
socks_recv_buf_used
)
ASSERT
(
client
->
socks_recv_buf_sent
<
client
->
socks_recv_buf_used
)
// set not waiting
// set not waiting
client
->
socks_recv_waiting
=
0
;
client
->
socks_recv_waiting
=
0
;
// possibly send more data
// possibly send more data
if
(
client_socks_recv_send_out
(
client
)
<
0
)
{
if
(
client_socks_recv_send_out
(
client
)
<
0
)
{
return
ERR_ABRT
;
return
ERR_ABRT
;
}
}
// we just queued some data, so it can't have been confirmed yet
// we just queued some data, so it can't have been confirmed yet
ASSERT
(
client
->
socks_recv_tcp_pending
>
0
)
ASSERT
(
client
->
socks_recv_tcp_pending
>
0
)
// continue receiving if needed
// continue receiving if needed
if
(
client
->
socks_recv_buf_used
==
-
1
&&
!
client
->
socks_closed
)
{
if
(
client
->
socks_recv_buf_used
==
-
1
&&
!
client
->
socks_closed
)
{
SYNC_DECL
SYNC_DECL
...
@@ -2340,17 +2309,17 @@ err_t client_sent_func (void *arg, struct tcp_pcb *tpcb, u16_t len)
...
@@ -2340,17 +2309,17 @@ err_t client_sent_func (void *arg, struct tcp_pcb *tpcb, u16_t len)
return
ERR_ABRT
;
return
ERR_ABRT
;
}
}
}
}
return
ERR_OK
;
return
ERR_OK
;
}
}
// have we sent everything after SOCKS was closed?
// have we sent everything after SOCKS was closed?
if
(
client
->
socks_closed
&&
client
->
socks_recv_tcp_pending
==
0
)
{
if
(
client
->
socks_closed
&&
client
->
socks_recv_tcp_pending
==
0
)
{
client_log
(
client
,
BLOG_INFO
,
"removing after SOCKS went down"
);
client_log
(
client
,
BLOG_INFO
,
"removing after SOCKS went down"
);
client_free_client
(
client
);
client_free_client
(
client
);
return
ERR_ABRT
;
return
ERR_ABRT
;
}
}
return
ERR_OK
;
return
ERR_OK
;
}
}
...
@@ -2360,9 +2329,9 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
...
@@ -2360,9 +2329,9 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
ASSERT
(
local_addr
.
type
==
BADDR_TYPE_IPV4
||
local_addr
.
type
==
BADDR_TYPE_IPV6
)
ASSERT
(
local_addr
.
type
==
BADDR_TYPE_IPV4
||
local_addr
.
type
==
BADDR_TYPE_IPV6
)
ASSERT
(
local_addr
.
type
==
remote_addr
.
type
)
ASSERT
(
local_addr
.
type
==
remote_addr
.
type
)
ASSERT
(
data_len
>=
0
)
ASSERT
(
data_len
>=
0
)
int
packet_length
=
0
;
int
packet_length
=
0
;
switch
(
local_addr
.
type
)
{
switch
(
local_addr
.
type
)
{
case
BADDR_TYPE_IPV4
:
{
case
BADDR_TYPE_IPV4
:
{
#ifdef ANDROID
#ifdef ANDROID
...
@@ -2370,14 +2339,14 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
...
@@ -2370,14 +2339,14 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
#else
#else
BLog
(
BLOG_INFO
,
"UDP: from udpgw %d bytes"
,
data_len
);
BLog
(
BLOG_INFO
,
"UDP: from udpgw %d bytes"
,
data_len
);
#endif
#endif
if
(
data_len
>
UINT16_MAX
-
(
sizeof
(
struct
ipv4_header
)
+
sizeof
(
struct
udp_header
))
||
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
))
data_len
>
BTap_GetMTU
(
&
device
)
-
(
int
)(
sizeof
(
struct
ipv4_header
)
+
sizeof
(
struct
udp_header
))
)
{
)
{
BLog
(
BLOG_ERROR
,
"UDP: packet is too large"
);
BLog
(
BLOG_ERROR
,
"UDP: packet is too large"
);
return
;
return
;
}
}
// build IP header
// build IP header
struct
ipv4_header
iph
;
struct
ipv4_header
iph
;
iph
.
version4_ihl4
=
IPV4_MAKE_VERSION_IHL
(
sizeof
(
iph
));
iph
.
version4_ihl4
=
IPV4_MAKE_VERSION_IHL
(
sizeof
(
iph
));
...
@@ -2391,7 +2360,7 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
...
@@ -2391,7 +2360,7 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
iph
.
source_address
=
remote_addr
.
ipv4
.
ip
;
iph
.
source_address
=
remote_addr
.
ipv4
.
ip
;
iph
.
destination_address
=
local_addr
.
ipv4
.
ip
;
iph
.
destination_address
=
local_addr
.
ipv4
.
ip
;
iph
.
checksum
=
ipv4_checksum
(
&
iph
,
NULL
,
0
);
iph
.
checksum
=
ipv4_checksum
(
&
iph
,
NULL
,
0
);
// build UDP header
// build UDP header
struct
udp_header
udph
;
struct
udp_header
udph
;
udph
.
source_port
=
remote_addr
.
ipv4
.
port
;
udph
.
source_port
=
remote_addr
.
ipv4
.
port
;
...
@@ -2399,21 +2368,21 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
...
@@ -2399,21 +2368,21 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
udph
.
length
=
hton16
(
sizeof
(
udph
)
+
data_len
);
udph
.
length
=
hton16
(
sizeof
(
udph
)
+
data_len
);
udph
.
checksum
=
hton16
(
0
);
udph
.
checksum
=
hton16
(
0
);
udph
.
checksum
=
udp_checksum
(
&
udph
,
data
,
data_len
,
iph
.
source_address
,
iph
.
destination_address
);
udph
.
checksum
=
udp_checksum
(
&
udph
,
data
,
data_len
,
iph
.
source_address
,
iph
.
destination_address
);
// write packet
// write packet
memcpy
(
device_write_buf
,
&
iph
,
sizeof
(
iph
));
memcpy
(
device_write_buf
,
&
iph
,
sizeof
(
iph
));
memcpy
(
device_write_buf
+
sizeof
(
iph
),
&
udph
,
sizeof
(
udph
));
memcpy
(
device_write_buf
+
sizeof
(
iph
),
&
udph
,
sizeof
(
udph
));
memcpy
(
device_write_buf
+
sizeof
(
iph
)
+
sizeof
(
udph
),
data
,
data_len
);
memcpy
(
device_write_buf
+
sizeof
(
iph
)
+
sizeof
(
udph
),
data
,
data_len
);
packet_length
=
sizeof
(
iph
)
+
sizeof
(
udph
)
+
data_len
;
packet_length
=
sizeof
(
iph
)
+
sizeof
(
udph
)
+
data_len
;
}
break
;
}
break
;
case
BADDR_TYPE_IPV6
:
{
case
BADDR_TYPE_IPV6
:
{
#ifdef ANDROID
#ifdef ANDROID
BLog
(
BLOG_INFO
,
"UDP/IPv6: from udprelay %d bytes"
,
data_len
);
BLog
(
BLOG_INFO
,
"UDP/IPv6: from udprelay %d bytes"
,
data_len
);
#else
#else
BLog
(
BLOG_INFO
,
"UDP/IPv6: from udpgw %d bytes"
,
data_len
);
BLog
(
BLOG_INFO
,
"UDP/IPv6: from udpgw %d bytes"
,
data_len
);
#endif
#endif
if
(
!
options
.
netif_ip6addr
)
{
if
(
!
options
.
netif_ip6addr
)
{
#ifdef ANDROID
#ifdef ANDROID
BLog
(
BLOG_ERROR
,
"got IPv6 packet from udprelay but IPv6 is disabled"
);
BLog
(
BLOG_ERROR
,
"got IPv6 packet from udprelay but IPv6 is disabled"
);
...
@@ -2422,14 +2391,14 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
...
@@ -2422,14 +2391,14 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
#endif
#endif
return
;
return
;
}
}
if
(
data_len
>
UINT16_MAX
-
sizeof
(
struct
udp_header
)
||
if
(
data_len
>
UINT16_MAX
-
sizeof
(
struct
udp_header
)
||
data_len
>
BTap_GetMTU
(
&
device
)
-
(
int
)(
sizeof
(
struct
ipv6_header
)
+
sizeof
(
struct
udp_header
))
data_len
>
BTap_GetMTU
(
&
device
)
-
(
int
)(
sizeof
(
struct
ipv6_header
)
+
sizeof
(
struct
udp_header
))
)
{
)
{
BLog
(
BLOG_ERROR
,
"UDP/IPv6: packet is too large"
);
BLog
(
BLOG_ERROR
,
"UDP/IPv6: packet is too large"
);
return
;
return
;
}
}
// build IPv6 header
// build IPv6 header
struct
ipv6_header
iph
;
struct
ipv6_header
iph
;
iph
.
version4_tc4
=
hton8
((
6
<<
4
));
iph
.
version4_tc4
=
hton8
((
6
<<
4
));
...
@@ -2440,7 +2409,7 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
...
@@ -2440,7 +2409,7 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
iph
.
hop_limit
=
hton8
(
64
);
iph
.
hop_limit
=
hton8
(
64
);
memcpy
(
iph
.
source_address
,
remote_addr
.
ipv6
.
ip
,
16
);
memcpy
(
iph
.
source_address
,
remote_addr
.
ipv6
.
ip
,
16
);
memcpy
(
iph
.
destination_address
,
local_addr
.
ipv6
.
ip
,
16
);
memcpy
(
iph
.
destination_address
,
local_addr
.
ipv6
.
ip
,
16
);
// build UDP header
// build UDP header
struct
udp_header
udph
;
struct
udp_header
udph
;
udph
.
source_port
=
remote_addr
.
ipv6
.
port
;
udph
.
source_port
=
remote_addr
.
ipv6
.
port
;
...
@@ -2448,7 +2417,7 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
...
@@ -2448,7 +2417,7 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
udph
.
length
=
hton16
(
sizeof
(
udph
)
+
data_len
);
udph
.
length
=
hton16
(
sizeof
(
udph
)
+
data_len
);
udph
.
checksum
=
hton16
(
0
);
udph
.
checksum
=
hton16
(
0
);
udph
.
checksum
=
udp_ip6_checksum
(
&
udph
,
data
,
data_len
,
iph
.
source_address
,
iph
.
destination_address
);
udph
.
checksum
=
udp_ip6_checksum
(
&
udph
,
data
,
data_len
,
iph
.
source_address
,
iph
.
destination_address
);
// write packet
// write packet
memcpy
(
device_write_buf
,
&
iph
,
sizeof
(
iph
));
memcpy
(
device_write_buf
,
&
iph
,
sizeof
(
iph
));
memcpy
(
device_write_buf
+
sizeof
(
iph
),
&
udph
,
sizeof
(
udph
));
memcpy
(
device_write_buf
+
sizeof
(
iph
),
&
udph
,
sizeof
(
udph
));
...
@@ -2456,7 +2425,7 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
...
@@ -2456,7 +2425,7 @@ void udpgw_client_handler_received (void *unused, BAddr local_addr, BAddr remote
packet_length
=
sizeof
(
iph
)
+
sizeof
(
udph
)
+
data_len
;
packet_length
=
sizeof
(
iph
)
+
sizeof
(
udph
)
+
data_len
;
}
break
;
}
break
;
}
}
// submit packet
// submit packet
BTap_Send
(
&
device
,
device_write_buf
,
packet_length
);
BTap_Send
(
&
device
,
device_write_buf
,
packet_length
);
}
}
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
View file @
383e9404
...
@@ -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
,
Executable
.
TUN2SOCKS
)
val
EXECUTABLES
=
Array
(
Executable
.
PDNSD
,
Executable
.
REDSOCKS
,
Executable
.
SS_TUNNEL
,
Executable
.
SS_LOCAL
)
// Helper functions
// Helper functions
def
updateListPreference
(
pref
:
Preference
,
value
:
String
)
{
def
updateListPreference
(
pref
:
Preference
,
value
:
String
)
{
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala
View file @
383e9404
...
@@ -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
,
LocalSocket
,
LocalSocketAddress
}
import
android.net.
{
LocalServerSocket
,
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,23 +322,25 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -322,23 +322,25 @@ class ShadowsocksVpnService extends VpnService with BaseService {
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
cmd
)
if
(
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
cmd
)
Console
.
runCommand
(
cmd
)
Tun2Socks
.
start
(
cmd
.
split
(
" "
))
}
Thread
.
sleep
(
300
)
def
startTunFdServer
()
{
spawn
{
// try {
val
fdServer
=
new
LocalServerSocket
(
"tun2socks"
)
val
localSocket
=
new
LocalSocket
()
try
{
localSocket
.
setFileDescriptorsForSend
(
Array
(
conn
.
getFileDescriptor
))
val
localSocket
=
fdServer
.
accept
()
val
localAddr
=
new
LocalSocketAddress
(
"tun2socks"
)
localSocket
.
setFileDescriptorsForSend
(
Array
(
conn
.
getFileDescriptor
))
localSocket
.
connect
(
localAddr
)
val
output
=
localSocket
.
getOutputStream
val
output
=
localSocket
.
getOutputStream
output
.
write
(
1
)
output
.
write
(
1
)
output
.
flush
()
output
.
flush
()
output
.
close
()
output
.
close
()
localSocket
.
close
()
localSocket
.
close
()
fdServer
.
close
()
// } catch {
}
catch
{
// case ex: Exception => // Ignored
case
ex
:
Exception
=>
Log
.
e
(
TAG
,
"Exception"
,
ex
)
// Ignored
// }
}
}
}
}
/** Called when the activity is first created. */
/** Called when the activity is first created. */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment