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
c7dd2f9a
Commit
c7dd2f9a
authored
Dec 26, 2012
by
Max Lv
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix shadowsocks-libev
parent
d01295b3
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
418 additions
and
302 deletions
+418
-302
jni/Android.mk
jni/Android.mk
+11
-11
jni/shadowsocks/local.c
jni/shadowsocks/local.c
+406
-291
jni/shadowsocks/local.h
jni/shadowsocks/local.h
+1
-0
libs/armeabi/libexec.so
libs/armeabi/libexec.so
+0
-0
libs/armeabi/libnode.so
libs/armeabi/libnode.so
+0
-0
No files found.
jni/Android.mk
View file @
c7dd2f9a
...
@@ -34,17 +34,17 @@ LOCAL_CFLAGS := -Wall -O2 -I$(LOCAL_PATH)/pdnsd
...
@@ -34,17 +34,17 @@ LOCAL_CFLAGS := -Wall -O2 -I$(LOCAL_PATH)/pdnsd
include
$(BUILD_EXECUTABLE)
include
$(BUILD_EXECUTABLE)
#
include $(CLEAR_VARS)
include
$(CLEAR_VARS)
#
LOCAL_MODULE := shadowsocks
LOCAL_MODULE
:=
shadowsocks
#
LOCAL_SRC_FILES := shadowsocks/local.c shadowsocks/encrypt.c
LOCAL_SRC_FILES
:=
shadowsocks/local.c shadowsocks/encrypt.c
#
LOCAL_CFLAGS := -Wall -O2 -I$(LOCAL_PATH)/libev/ -I$(LOCAL_PATH)/openssl/include -std=c99
LOCAL_CFLAGS
:=
-Wall
-O2
-I
$(LOCAL_PATH)
/libev/
-I
$(LOCAL_PATH)
/openssl/include
-std
=
c99
#
LOCAL_STATIC_LIBRARIES := libev libcrypto
LOCAL_STATIC_LIBRARIES
:=
libev libcrypto
#
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS
:=
-llog
#
include $(BUILD_EXECUTABLE)
include
$(BUILD_EXECUTABLE)
include
$(CLEAR_VARS)
include
$(CLEAR_VARS)
...
@@ -68,9 +68,9 @@ LOCAL_LDLIBS := -ldl
...
@@ -68,9 +68,9 @@ LOCAL_LDLIBS := -ldl
include
$(BUILD_SHARED_LIBRARY)
include
$(BUILD_SHARED_LIBRARY)
#
subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \
subdirs
:=
$(
addprefix
$(LOCAL_PATH)
/openssl/,
$(
addsuffix
/Android.mk,
\
#
crypto \
crypto
\
#
))
))
#
include $(subdirs)
include
$(subdirs)
jni/shadowsocks/local.c
View file @
c7dd2f9a
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
#include <linux/limits.h>
#include <linux/limits.h>
#include "local.h"
#include "local.h"
#include "socks5.h"
#include "encrypt.h"
#include "encrypt.h"
#include "android.h"
#include "android.h"
...
@@ -53,7 +54,6 @@ int create_and_bind(const char *port) {
...
@@ -53,7 +54,6 @@ int create_and_bind(const char *port) {
memset
(
&
hints
,
0
,
sizeof
(
struct
addrinfo
));
memset
(
&
hints
,
0
,
sizeof
(
struct
addrinfo
));
hints
.
ai_family
=
AF_UNSPEC
;
/* Return IPv4 and IPv6 choices */
hints
.
ai_family
=
AF_UNSPEC
;
/* Return IPv4 and IPv6 choices */
hints
.
ai_socktype
=
SOCK_STREAM
;
/* We want a TCP socket */
hints
.
ai_socktype
=
SOCK_STREAM
;
/* We want a TCP socket */
hints
.
ai_flags
=
AI_PASSIVE
;
/* All interfaces */
s
=
getaddrinfo
(
"0.0.0.0"
,
port
,
&
hints
,
&
result
);
s
=
getaddrinfo
(
"0.0.0.0"
,
port
,
&
hints
,
&
result
);
if
(
s
!=
0
)
{
if
(
s
!=
0
)
{
...
@@ -90,330 +90,445 @@ int create_and_bind(const char *port) {
...
@@ -90,330 +90,445 @@ int create_and_bind(const char *port) {
}
}
static
void
server_recv_cb
(
EV_P_
ev_io
*
w
,
int
revents
)
{
static
void
server_recv_cb
(
EV_P_
ev_io
*
w
,
int
revents
)
{
struct
server_ctx
*
server_recv_ctx
=
(
struct
server_ctx
*
)
w
;
struct
server_ctx
*
server_recv_ctx
=
(
struct
server_ctx
*
)
w
;
struct
server
*
server
=
server_recv_ctx
->
server
;
struct
server
*
server
=
server_recv_ctx
->
server
;
struct
remote
*
remote
=
server
->
remote
;
struct
remote
*
remote
=
server
->
remote
;
if
(
remote
==
NULL
)
{
if
(
remote
==
NULL
)
{
close_and_free_server
(
EV_A_
server
);
close_and_free_server
(
EV_A_
server
);
return
;
return
;
}
}
while
(
1
)
{
ssize_t
r
=
recv
(
server
->
fd
,
remote
->
buf
,
BUF_SIZE
,
0
);
char
*
buf
=
remote
->
buf
;
if
(
r
==
0
)
{
int
*
buf_len
=
&
remote
->
buf_len
;
// connection closed
if
(
server
->
stage
!=
5
)
{
remote
->
buf_len
=
0
;
buf
=
server
->
buf
;
close_and_free_server
(
EV_A_
server
);
buf_len
=
&
server
->
buf_len
;
if
(
remote
!=
NULL
)
{
}
ev_io_start
(
EV_A_
&
remote
->
send_ctx
->
io
);
while
(
1
)
{
ssize_t
r
=
recv
(
server
->
fd
,
buf
,
BUF_SIZE
,
0
);
if
(
r
==
0
)
{
// connection closed
*
buf_len
=
0
;
close_and_free_server
(
EV_A_
server
);
if
(
remote
!=
NULL
)
{
ev_io_start
(
EV_A_
&
remote
->
send_ctx
->
io
);
}
return
;
}
else
if
(
r
<
0
)
{
if
(
errno
==
EAGAIN
)
{
// no data
// continue to wait for recv
break
;
}
else
{
perror
(
"server recv"
);
close_and_free_server
(
EV_A_
server
);
close_and_free_remote
(
EV_A_
remote
);
return
;
}
}
// local socks5 server
if
(
server
->
stage
==
5
)
{
encrypt
(
remote
->
buf
,
r
);
int
w
=
send
(
remote
->
fd
,
remote
->
buf
,
r
,
0
);
if
(
w
==
-
1
)
{
if
(
errno
==
EAGAIN
)
{
// no data, wait for send
ev_io_stop
(
EV_A_
&
server_recv_ctx
->
io
);
ev_io_start
(
EV_A_
&
remote
->
send_ctx
->
io
);
break
;
}
else
{
perror
(
"send"
);
close_and_free_server
(
EV_A_
server
);
close_and_free_remote
(
EV_A_
remote
);
return
;
}
}
else
if
(
w
<
r
)
{
char
*
pt
=
remote
->
buf
;
char
*
et
=
pt
+
min
(
w
,
BUF_SIZE
);
while
(
pt
<
et
)
{
*
pt
=
*
(
pt
+
w
);
pt
++
;
}
remote
->
buf_len
=
r
-
w
;
ev_io_stop
(
EV_A_
&
server_recv_ctx
->
io
);
ev_io_start
(
EV_A_
&
remote
->
send_ctx
->
io
);
break
;
}
}
return
;
}
else
if
(
server
->
stage
==
0
)
{
}
else
if
(
r
<
0
)
{
struct
method_select_response
response
;
perror
(
"recv"
);
response
.
ver
=
VERSION
;
if
(
errno
==
EAGAIN
)
{
response
.
method
=
0
;
// no data
char
*
send_buf
=
(
char
*
)
&
response
;
// continue to wait for recv
send
(
server
->
fd
,
send_buf
,
sizeof
(
response
),
MSG_NOSIGNAL
);
break
;
server
->
stage
=
1
;
}
else
{
return
;
close_and_free_server
(
EV_A_
server
);
}
else
if
(
server
->
stage
==
1
)
{
struct
socks5_request
*
request
=
(
struct
socks5_request
*
)
server
->
buf
;
if
(
request
->
cmd
!=
1
)
{
LOGE
(
"unsupported cmd: %d
\n
"
,
request
->
cmd
);
struct
socks5_response
response
;
response
.
ver
=
VERSION
;
response
.
rep
=
CMD_NOT_SUPPORTED
;
response
.
rsv
=
0
;
response
.
atyp
=
1
;
char
*
send_buf
=
(
char
*
)
&
response
;
send
(
server
->
fd
,
send_buf
,
4
,
MSG_NOSIGNAL
);
close_and_free_server
(
EV_A_
server
);
close_and_free_remote
(
EV_A_
remote
);
close_and_free_remote
(
EV_A_
remote
);
return
;
return
;
}
}
}
encrypt
(
remote
->
buf
,
r
);
char
addr_to_send
[
256
];
int
w
=
send
(
remote
->
fd
,
remote
->
buf
,
r
,
MSG_NOSIGNAL
);
unsigned
char
addr_len
=
0
;
if
(
w
==
-
1
)
{
addr_to_send
[
addr_len
++
]
=
request
->
atyp
;
perror
(
"send"
);
if
(
errno
==
EAGAIN
)
{
// get remote addr and port
// no data, wait for send
if
(
request
->
atyp
==
1
)
{
ev_io_stop
(
EV_A_
&
server_recv_ctx
->
io
);
ev_io_start
(
EV_A_
&
remote
->
send_ctx
->
io
);
// IP V4
break
;
struct
in_addr
*
in_addr
;
}
else
{
in_addr
=
(
struct
in_addr
*
)(
server
->
buf
+
4
);
close_and_free_server
(
EV_A_
server
);
char
*
addr_buf
=
inet_ntoa
(
*
in_addr
);
unsigned
char
name_len
=
strlen
(
addr_buf
);
memcpy
(
addr_to_send
+
addr_len
,
addr_buf
,
name_len
);
addr_len
+=
name_len
;
// get port
addr_to_send
[
addr_len
++
]
=
*
(
unsigned
char
*
)(
server
->
buf
+
4
+
4
);
addr_to_send
[
addr_len
++
]
=
*
(
unsigned
char
*
)(
server
->
buf
+
4
+
4
+
1
);
addr_to_send
[
addr_len
]
=
0
;
}
else
if
(
request
->
atyp
==
3
)
{
// Domain name
unsigned
char
name_len
=
*
(
unsigned
char
*
)(
server
->
buf
+
4
);
addr_to_send
[
addr_len
++
]
=
name_len
;
memcpy
(
addr_to_send
+
addr_len
,
server
->
buf
+
4
+
1
,
name_len
);
addr_len
+=
name_len
;
// get port
addr_to_send
[
addr_len
++
]
=
*
(
unsigned
char
*
)(
server
->
buf
+
4
+
1
+
name_len
);
addr_to_send
[
addr_len
++
]
=
*
(
unsigned
char
*
)(
server
->
buf
+
4
+
1
+
name_len
+
1
);
addr_to_send
[
addr_len
]
=
0
;
}
else
{
LOGE
(
"unsupported addrtype: %d
\n
"
,
request
->
atyp
);
close_and_free_server
(
EV_A_
server
);
close_and_free_remote
(
EV_A_
remote
);
close_and_free_remote
(
EV_A_
remote
);
return
;
}
send_encrypt
(
remote
->
fd
,
addr_to_send
,
addr_len
,
0
);
// Fake reply
struct
socks5_response
response
;
response
.
ver
=
VERSION
;
response
.
rep
=
0
;
response
.
rsv
=
0
;
response
.
atyp
=
1
;
struct
in_addr
sin_addr
;
inet_aton
(
"0.0.0.0"
,
&
sin_addr
);
memcpy
(
server
->
buf
,
&
response
,
4
);
memcpy
(
server
->
buf
+
4
,
&
sin_addr
,
sizeof
(
struct
in_addr
));
*
((
unsigned
short
*
)(
server
->
buf
+
4
+
sizeof
(
struct
in_addr
)))
=
(
unsigned
short
)
htons
(
atoi
(
_remote_port
));
int
reply_size
=
4
+
sizeof
(
struct
in_addr
)
+
sizeof
(
unsigned
short
);
int
r
=
send
(
server
->
fd
,
server
->
buf
,
reply_size
,
MSG_NOSIGNAL
);
if
(
r
<
reply_size
)
{
LOGE
(
"header not complete sent
\n
"
);
close_and_free_remote
(
EV_A_
remote
);
close_and_free_server
(
EV_A_
server
);
return
;
return
;
}
}
}
else
if
(
w
<
r
)
{
char
*
pt
;
server
->
stage
=
5
;
for
(
pt
=
remote
->
buf
;
pt
<
pt
+
min
(
w
,
BUF_SIZE
);
pt
++
)
{
*
pt
=
*
(
pt
+
w
);
}
remote
->
buf_len
=
r
-
w
;
ev_io_stop
(
EV_A_
&
server_recv_ctx
->
io
);
ev_io_start
(
EV_A_
&
remote
->
send_ctx
->
io
);
break
;
}
}
}
}
}
}
static
void
server_send_cb
(
EV_P_
ev_io
*
w
,
int
revents
)
{
static
void
server_send_cb
(
EV_P_
ev_io
*
w
,
int
revents
)
{
struct
server_ctx
*
server_send_ctx
=
(
struct
server_ctx
*
)
w
;
struct
server_ctx
*
server_send_ctx
=
(
struct
server_ctx
*
)
w
;
struct
server
*
server
=
server_send_ctx
->
server
;
struct
server
*
server
=
server_send_ctx
->
server
;
struct
remote
*
remote
=
server
->
remote
;
struct
remote
*
remote
=
server
->
remote
;
if
(
server
->
buf_len
==
0
)
{
if
(
server
->
buf_len
==
0
)
{
// close and free
// close and free
close_and_free_server
(
EV_A_
server
);
close_and_free_server
(
EV_A_
server
);
close_and_free_remote
(
EV_A_
remote
);
close_and_free_remote
(
EV_A_
remote
);
return
;
return
;
}
else
{
}
else
{
// has data to send
// has data to send
ssize_t
r
=
send
(
server
->
fd
,
server
->
buf
,
ssize_t
r
=
send
(
server
->
fd
,
server
->
buf
,
server
->
buf_len
,
0
);
server
->
buf_len
,
0
);
if
(
r
<
0
)
{
if
(
r
<
0
)
{
perror
(
"send"
);
if
(
errno
!=
EAGAIN
)
{
if
(
errno
!=
EAGAIN
)
{
perror
(
"send"
);
close_and_free_server
(
EV_A_
server
);
close_and_free_server
(
EV_A_
server
);
close_and_free_remote
(
EV_A_
remote
);
close_and_free_remote
(
EV_A_
remote
);
return
;
return
;
}
}
return
;
return
;
}
}
if
(
r
<
server
->
buf_len
)
{
if
(
r
<
server
->
buf_len
)
{
LOGD
(
"r=%d
\n
"
,
r
);
// partly sent, move memory, wait for the next time to send
LOGD
(
"server->buf_len=%d
\n
"
,
server
->
buf_len
)
;
char
*
pt
=
server
->
buf
;
// partly sent, move memory, wait for the next time to send
char
*
et
=
pt
+
min
(
r
,
BUF_SIZE
);
char
*
pt
;
while
(
pt
<
et
)
{
for
(
pt
=
server
->
buf
;
pt
<
pt
+
min
(
r
,
BUF_SIZE
);
pt
++
)
{
*
pt
=
*
(
pt
+
r
);
*
pt
=
*
(
pt
+
r
)
;
pt
++
;
}
}
server
->
buf_len
-=
r
;
server
->
buf_len
-=
r
;
return
;
return
;
}
else
{
}
else
{
// all sent out, wait for reading
// all sent out, wait for reading
ev_io_stop
(
EV_A_
&
server_send_ctx
->
io
);
ev_io_stop
(
EV_A_
&
server_send_ctx
->
io
);
if
(
remote
!=
NULL
)
{
if
(
remote
!=
NULL
)
{
ev_io_start
(
EV_A_
&
remote
->
recv_ctx
->
io
);
ev_io_start
(
EV_A_
&
remote
->
recv_ctx
->
io
);
}
else
{
}
else
{
close_and_free_server
(
EV_A_
server
);
close_and_free_server
(
EV_A_
server
);
close_and_free_remote
(
EV_A_
remote
);
close_and_free_remote
(
EV_A_
remote
);
return
;
return
;
}
}
}
}
}
}
}
}
static
void
remote_recv_cb
(
EV_P_
ev_io
*
w
,
int
revents
)
{
static
void
remote_recv_cb
(
EV_P_
ev_io
*
w
,
int
revents
)
{
struct
remote_ctx
*
remote_recv_ctx
=
(
struct
remote_ctx
*
)
w
;
struct
remote_ctx
*
remote_recv_ctx
=
(
struct
remote_ctx
*
)
w
;
struct
remote
*
remote
=
remote_recv_ctx
->
remote
;
struct
remote
*
remote
=
remote_recv_ctx
->
remote
;
struct
server
*
server
=
remote
->
server
;
struct
server
*
server
=
remote
->
server
;
if
(
server
==
NULL
)
{
if
(
server
==
NULL
)
{
close_and_free_remote
(
EV_A_
remote
);
close_and_free_remote
(
EV_A_
remote
);
return
;
return
;
}
}
while
(
1
)
{
while
(
1
)
{
ssize_t
r
=
recv
(
remote
->
fd
,
server
->
buf
,
BUF_SIZE
,
0
);
ssize_t
r
=
recv
(
remote
->
fd
,
server
->
buf
,
BUF_SIZE
,
0
);
/*LOGD("after recv: r=%d\n", r);*/
if
(
r
==
0
)
{
if
(
r
==
0
)
{
// connection closed
// connection closed
server
->
buf_len
=
0
;
server
->
buf_len
=
0
;
close_and_free_remote
(
EV_A_
remote
);
close_and_free_remote
(
EV_A_
remote
);
if
(
server
!=
NULL
)
{
if
(
server
!=
NULL
)
{
ev_io_start
(
EV_A_
&
server
->
send_ctx
->
io
);
ev_io_start
(
EV_A_
&
server
->
send_ctx
->
io
);
}
}
return
;
return
;
}
else
if
(
r
<
0
)
{
}
else
if
(
r
<
0
)
{
perror
(
"recv"
);
if
(
errno
==
EAGAIN
)
{
if
(
errno
==
EAGAIN
)
{
// no data
// no data
// continue to wait for recv
// continue to wait for recv
break
;
break
;
}
else
{
}
else
{
perror
(
"remote recv"
);
close_and_free_server
(
EV_A_
server
);
close_and_free_server
(
EV_A_
server
);
close_and_free_remote
(
EV_A_
remote
);
close_and_free_remote
(
EV_A_
remote
);
return
;
return
;
}
}
}
}
decrypt
(
server
->
buf
,
r
);
decrypt
(
server
->
buf
,
r
);
int
w
=
send
(
server
->
fd
,
server
->
buf
,
r
,
MSG_NOSIGNAL
);
int
w
=
send
(
server
->
fd
,
server
->
buf
,
r
,
MSG_NOSIGNAL
);
/*LOGD("after send: w=%d\n", w);*/
if
(
w
==
-
1
)
{
if
(
w
==
-
1
)
{
if
(
errno
==
EAGAIN
)
{
perror
(
"send"
);
// no data, wait for send
if
(
errno
==
EAGAIN
)
{
ev_io_stop
(
EV_A_
&
remote_recv_ctx
->
io
);
// no data, wait for send
ev_io_start
(
EV_A_
&
server
->
send_ctx
->
io
);
ev_io_stop
(
EV_A_
&
remote_recv_ctx
->
io
);
break
;
ev_io_start
(
EV_A_
&
server
->
send_ctx
->
io
);
}
else
{
break
;
perror
(
"send"
);
}
else
{
close_and_free_server
(
EV_A_
server
);
close_and_free_server
(
EV_A_
server
);
close_and_free_remote
(
EV_A_
remote
);
close_and_free_remote
(
EV_A_
remote
);
return
;
return
;
}
}
}
else
if
(
w
<
r
)
{
}
else
if
(
w
<
r
)
{
char
*
pt
=
server
->
buf
;
char
*
pt
;
char
*
et
=
pt
+
min
(
w
,
BUF_SIZE
);
for
(
pt
=
server
->
buf
;
pt
<
pt
+
min
(
w
,
BUF_SIZE
);
pt
++
)
{
while
(
pt
<
et
)
{
*
pt
=
*
(
pt
+
w
);
*
pt
=
*
(
pt
+
w
);
}
pt
++
;
server
->
buf_len
=
r
-
w
;
}
ev_io_stop
(
EV_A_
&
remote_recv_ctx
->
io
);
server
->
buf_len
=
r
-
w
;
ev_io_start
(
EV_A_
&
server
->
send_ctx
->
io
);
ev_io_stop
(
EV_A_
&
remote_recv_ctx
->
io
);
break
;
ev_io_start
(
EV_A_
&
server
->
send_ctx
->
io
);
}
break
;
}
}
}
}
}
static
void
remote_send_cb
(
EV_P_
ev_io
*
w
,
int
revents
)
{
static
void
remote_send_cb
(
EV_P_
ev_io
*
w
,
int
revents
)
{
struct
remote_ctx
*
remote_send_ctx
=
(
struct
remote_ctx
*
)
w
;
struct
remote_ctx
*
remote_send_ctx
=
(
struct
remote_ctx
*
)
w
;
struct
remote
*
remote
=
remote_send_ctx
->
remote
;
struct
remote
*
remote
=
remote_send_ctx
->
remote
;
struct
server
*
server
=
remote
->
server
;
struct
server
*
server
=
remote
->
server
;
if
(
!
remote_send_ctx
->
connected
)
{
socklen_t
len
;
if
(
!
remote_send_ctx
->
connected
)
{
struct
sockaddr_storage
addr
;
len
=
sizeof
addr
;
socklen_t
len
;
int
r
=
getpeername
(
remote
->
fd
,
(
struct
sockaddr
*
)
&
addr
,
&
len
);
struct
sockaddr_storage
addr
;
if
(
r
==
0
)
{
len
=
sizeof
addr
;
remote_send_ctx
->
connected
=
1
;
int
r
=
getpeername
(
remote
->
fd
,
(
struct
sockaddr
*
)
&
addr
,
&
len
);
ev_io_stop
(
EV_A_
&
remote_send_ctx
->
io
);
if
(
r
==
0
)
{
ev_io_start
(
EV_A_
&
server
->
recv_ctx
->
io
);
remote_send_ctx
->
connected
=
1
;
ev_io_start
(
EV_A_
&
remote
->
recv_ctx
->
io
);
ev_io_stop
(
EV_A_
&
remote_send_ctx
->
io
);
}
else
{
ev_io_start
(
EV_A_
&
server
->
recv_ctx
->
io
);
perror
(
"getpeername"
);
ev_io_start
(
EV_A_
&
remote
->
recv_ctx
->
io
);
// not connected
}
else
{
close_and_free_remote
(
EV_A_
remote
);
perror
(
"getpeername"
);
close_and_free_server
(
EV_A_
server
);
// not connected
return
;
close_and_free_remote
(
EV_A_
remote
);
}
close_and_free_server
(
EV_A_
server
);
}
else
{
return
;
if
(
remote
->
buf_len
==
0
)
{
}
// close and free
}
else
{
close_and_free_remote
(
EV_A_
remote
);
if
(
remote
->
buf_len
==
0
)
{
close_and_free_server
(
EV_A_
server
);
// close and free
return
;
close_and_free_remote
(
EV_A_
remote
);
}
else
{
close_and_free_server
(
EV_A_
server
);
// has data to send
return
;
ssize_t
r
=
send
(
remote
->
fd
,
remote
->
buf
,
}
else
{
remote
->
buf_len
,
0
);
// has data to send
if
(
r
<
0
)
{
ssize_t
r
=
send
(
remote
->
fd
,
remote
->
buf
,
perror
(
"send"
);
remote
->
buf_len
,
0
);
if
(
errno
!=
EAGAIN
)
{
if
(
r
<
0
)
{
// close and free
if
(
errno
!=
EAGAIN
)
{
close_and_free_remote
(
EV_A_
remote
);
perror
(
"send"
);
close_and_free_server
(
EV_A_
server
);
// close and free
return
;
close_and_free_remote
(
EV_A_
remote
);
}
close_and_free_server
(
EV_A_
server
);
return
;
return
;
}
}
if
(
r
<
remote
->
buf_len
)
{
return
;
// partly sent, move memory, wait for the next time to send
}
char
*
pt
;
if
(
r
<
remote
->
buf_len
)
{
for
(
pt
=
remote
->
buf
;
pt
<
pt
+
min
(
r
,
BUF_SIZE
);
pt
++
)
{
// partly sent, move memory, wait for the next time to send
char
*
pt
=
remote
->
buf
;
char
*
et
=
pt
+
min
(
r
,
BUF_SIZE
);
while
(
pt
<
et
)
{
*
pt
=
*
(
pt
+
r
);
*
pt
=
*
(
pt
+
r
);
pt
++
;
}
}
remote
->
buf_len
-=
r
;
remote
->
buf_len
-=
r
;
return
;
return
;
}
else
{
}
else
{
// all sent out, wait for reading
// all sent out, wait for reading
ev_io_stop
(
EV_A_
&
remote_send_ctx
->
io
);
ev_io_stop
(
EV_A_
&
remote_send_ctx
->
io
);
if
(
server
!=
NULL
)
{
if
(
server
!=
NULL
)
{
ev_io_start
(
EV_A_
&
server
->
recv_ctx
->
io
);
ev_io_start
(
EV_A_
&
server
->
recv_ctx
->
io
);
}
else
{
}
else
{
close_and_free_remote
(
EV_A_
remote
);
close_and_free_remote
(
EV_A_
remote
);
close_and_free_server
(
EV_A_
server
);
close_and_free_server
(
EV_A_
server
);
return
;
return
;
}
}
}
}
}
}
}
}
}
}
struct
remote
*
new_remote
(
int
fd
)
{
struct
remote
*
new_remote
(
int
fd
)
{
struct
remote
*
remote
;
struct
remote
*
remote
;
remote
=
malloc
(
sizeof
(
struct
remote
));
remote
=
malloc
(
sizeof
(
struct
remote
));
remote
->
fd
=
fd
;
remote
->
fd
=
fd
;
remote
->
recv_ctx
=
malloc
(
sizeof
(
struct
remote_ctx
));
remote
->
recv_ctx
=
malloc
(
sizeof
(
struct
remote_ctx
));
remote
->
send_ctx
=
malloc
(
sizeof
(
struct
remote_ctx
));
remote
->
send_ctx
=
malloc
(
sizeof
(
struct
remote_ctx
));
ev_io_init
(
&
remote
->
recv_ctx
->
io
,
remote_recv_cb
,
fd
,
EV_READ
);
ev_io_init
(
&
remote
->
recv_ctx
->
io
,
remote_recv_cb
,
fd
,
EV_READ
);
ev_io_init
(
&
remote
->
send_ctx
->
io
,
remote_send_cb
,
fd
,
EV_WRITE
);
ev_io_init
(
&
remote
->
send_ctx
->
io
,
remote_send_cb
,
fd
,
EV_WRITE
);
remote
->
recv_ctx
->
remote
=
remote
;
remote
->
recv_ctx
->
remote
=
remote
;
remote
->
recv_ctx
->
connected
=
0
;
remote
->
recv_ctx
->
connected
=
0
;
remote
->
send_ctx
->
remote
=
remote
;
remote
->
send_ctx
->
remote
=
remote
;
remote
->
send_ctx
->
connected
=
0
;
remote
->
send_ctx
->
connected
=
0
;
return
remote
;
return
remote
;
}
}
void
free_remote
(
struct
remote
*
remote
)
{
void
free_remote
(
struct
remote
*
remote
)
{
if
(
remote
!=
NULL
)
{
if
(
remote
!=
NULL
)
{
if
(
remote
->
server
!=
NULL
)
{
if
(
remote
->
server
!=
NULL
)
{
remote
->
server
->
remote
=
NULL
;
remote
->
server
->
remote
=
NULL
;
}
}
free
(
remote
->
recv_ctx
);
free
(
remote
->
recv_ctx
);
free
(
remote
->
send_ctx
);
free
(
remote
->
send_ctx
);
free
(
remote
);
free
(
remote
);
}
}
}
}
void
close_and_free_remote
(
EV_P_
struct
remote
*
remote
)
{
void
close_and_free_remote
(
EV_P_
struct
remote
*
remote
)
{
if
(
remote
!=
NULL
)
{
if
(
remote
!=
NULL
)
{
ev_io_stop
(
EV_A_
&
remote
->
send_ctx
->
io
);
ev_io_stop
(
EV_A_
&
remote
->
send_ctx
->
io
);
ev_io_stop
(
EV_A_
&
remote
->
recv_ctx
->
io
);
ev_io_stop
(
EV_A_
&
remote
->
recv_ctx
->
io
);
close
(
remote
->
fd
);
close
(
remote
->
fd
);
free_remote
(
remote
);
free_remote
(
remote
);
}
}
}
}
struct
server
*
new_server
(
int
fd
)
{
struct
server
*
new_server
(
int
fd
)
{
struct
server
*
server
;
struct
server
*
server
;
server
=
malloc
(
sizeof
(
struct
server
));
server
=
malloc
(
sizeof
(
struct
server
));
server
->
fd
=
fd
;
server
->
fd
=
fd
;
server
->
recv_ctx
=
malloc
(
sizeof
(
struct
server_ctx
));
server
->
recv_ctx
=
malloc
(
sizeof
(
struct
server_ctx
));
server
->
send_ctx
=
malloc
(
sizeof
(
struct
server_ctx
));
server
->
send_ctx
=
malloc
(
sizeof
(
struct
server_ctx
));
ev_io_init
(
&
server
->
recv_ctx
->
io
,
server_recv_cb
,
fd
,
EV_READ
);
ev_io_init
(
&
server
->
recv_ctx
->
io
,
server_recv_cb
,
fd
,
EV_READ
);
ev_io_init
(
&
server
->
send_ctx
->
io
,
server_send_cb
,
fd
,
EV_WRITE
);
ev_io_init
(
&
server
->
send_ctx
->
io
,
server_send_cb
,
fd
,
EV_WRITE
);
server
->
recv_ctx
->
server
=
server
;
server
->
recv_ctx
->
server
=
server
;
server
->
recv_ctx
->
connected
=
0
;
server
->
recv_ctx
->
connected
=
0
;
server
->
send_ctx
->
server
=
server
;
server
->
send_ctx
->
server
=
server
;
server
->
send_ctx
->
connected
=
0
;
server
->
send_ctx
->
connected
=
0
;
return
server
;
server
->
stage
=
0
;
return
server
;
}
}
void
free_server
(
struct
server
*
server
)
{
void
free_server
(
struct
server
*
server
)
{
if
(
server
!=
NULL
)
{
if
(
server
!=
NULL
)
{
if
(
server
->
remote
!=
NULL
)
{
if
(
server
->
remote
!=
NULL
)
{
server
->
remote
->
server
=
NULL
;
server
->
remote
->
server
=
NULL
;
}
}
free
(
server
->
recv_ctx
);
free
(
server
->
recv_ctx
);
free
(
server
->
send_ctx
);
free
(
server
->
send_ctx
);
free
(
server
);
free
(
server
);
}
}
}
}
void
close_and_free_server
(
EV_P_
struct
server
*
server
)
{
void
close_and_free_server
(
EV_P_
struct
server
*
server
)
{
if
(
server
!=
NULL
)
{
if
(
server
!=
NULL
)
{
ev_io_stop
(
EV_A_
&
server
->
send_ctx
->
io
);
ev_io_stop
(
EV_A_
&
server
->
send_ctx
->
io
);
ev_io_stop
(
EV_A_
&
server
->
recv_ctx
->
io
);
ev_io_stop
(
EV_A_
&
server
->
recv_ctx
->
io
);
close
(
server
->
fd
);
close
(
server
->
fd
);
free_server
(
server
);
free_server
(
server
);
}
}
}
}
static
void
accept_cb
(
EV_P_
ev_io
*
w
,
int
revents
)
static
void
accept_cb
(
EV_P_
ev_io
*
w
,
int
revents
)
{
{
struct
listen_ctx
*
listener
=
(
struct
listen_ctx
*
)
w
;
struct
listen_ctx
*
listener
=
(
struct
listen_ctx
*
)
w
;
int
serverfd
;
int
serverfd
;
while
(
1
)
{
while
(
1
)
{
serverfd
=
accept
(
listener
->
fd
,
NULL
,
NULL
);
serverfd
=
accept
(
listener
->
fd
,
NULL
,
NULL
);
if
(
serverfd
==
-
1
)
{
if
(
serverfd
==
-
1
)
{
perror
(
"accept"
);
perror
(
"accept"
);
break
;
break
;
}
}
setnonblocking
(
serverfd
);
setnonblocking
(
serverfd
);
struct
server
*
server
=
new_server
(
serverfd
);
struct
server
*
server
=
new_server
(
serverfd
);
struct
addrinfo
hints
,
*
res
;
struct
addrinfo
hints
,
*
res
;
int
sockfd
;
int
sockfd
;
memset
(
&
hints
,
0
,
sizeof
hints
);
memset
(
&
hints
,
0
,
sizeof
hints
);
hints
.
ai_family
=
AF_UNSPEC
;
hints
.
ai_family
=
AF_UNSPEC
;
hints
.
ai_socktype
=
SOCK_STREAM
;
hints
.
ai_socktype
=
SOCK_STREAM
;
getaddrinfo
(
_server
,
_remote_port
,
&
hints
,
&
res
);
getaddrinfo
(
_server
,
_remote_port
,
&
hints
,
&
res
);
sockfd
=
socket
(
res
->
ai_family
,
res
->
ai_socktype
,
res
->
ai_protocol
);
sockfd
=
socket
(
res
->
ai_family
,
res
->
ai_socktype
,
res
->
ai_protocol
);
if
(
sockfd
<
0
)
{
if
(
sockfd
<
0
)
{
perror
(
"socket"
);
perror
(
"socket"
);
close
(
sockfd
);
close
(
sockfd
);
free_server
(
server
);
free_server
(
server
);
continue
;
continue
;
}
}
setnonblocking
(
sockfd
);
setnonblocking
(
sockfd
);
struct
remote
*
remote
=
new_remote
(
sockfd
);
struct
remote
*
remote
=
new_remote
(
sockfd
);
server
->
remote
=
remote
;
server
->
remote
=
remote
;
remote
->
server
=
server
;
remote
->
server
=
server
;
connect
(
sockfd
,
res
->
ai_addr
,
res
->
ai_addrlen
);
connect
(
sockfd
,
res
->
ai_addr
,
res
->
ai_addrlen
);
freeaddrinfo
(
res
);
freeaddrinfo
(
res
);
// listen to remote connected event
// listen to remote connected event
ev_io_start
(
EV_A_
&
remote
->
send_ctx
->
io
);
ev_io_start
(
EV_A_
&
remote
->
send_ctx
->
io
);
break
;
break
;
}
}
}
}
int
main
(
int
argc
,
char
**
argv
)
int
main
(
int
argc
,
char
**
argv
)
...
...
jni/shadowsocks/local.h
View file @
c7dd2f9a
...
@@ -13,6 +13,7 @@ struct listen_ctx {
...
@@ -13,6 +13,7 @@ struct listen_ctx {
struct
server
{
struct
server
{
int
fd
;
int
fd
;
char
buf
[
BUF_SIZE
];
// server send from, remote recv into
char
buf
[
BUF_SIZE
];
// server send from, remote recv into
char
stage
;
int
buf_len
;
int
buf_len
;
struct
server_ctx
*
recv_ctx
;
struct
server_ctx
*
recv_ctx
;
struct
server_ctx
*
send_ctx
;
struct
server_ctx
*
send_ctx
;
...
...
libs/armeabi/libexec.so
View file @
c7dd2f9a
No preview for this file type
libs/armeabi/libnode.so
View file @
c7dd2f9a
No preview for this file type
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