mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-30 05:11:14 +00:00
add traffic stat IPC calls
This commit is contained in:
+53
-3
@@ -55,10 +55,10 @@ int protect_socket(int fd)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set timeout to 100us
|
||||
// Set timeout to 1s
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 1; /* 0 Secs Timeout */
|
||||
tv.tv_usec = 0; // Not init'ing this can cause strange errors
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
|
||||
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval));
|
||||
|
||||
@@ -92,3 +92,53 @@ int protect_socket(int fd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int send_traffic_stat(uint64_t tx, uint64_t rx)
|
||||
{
|
||||
int sock;
|
||||
struct sockaddr_un addr;
|
||||
|
||||
if ( (sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
||||
LOGE("[android] socket() failed: %s (socket fd = %d)\n", strerror(errno), sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set timeout to 1s
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
|
||||
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval));
|
||||
|
||||
const char path[] = "/data/data/com.github.shadowsocks/stat_path";
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
|
||||
|
||||
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||
LOGE("[android] connect() failed: %s (socket fd = %d)\n", strerror(errno), sock);
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char stat[256] = {0};
|
||||
snprintf(stat, 256, "%" PRIu64 "|%" PRIu64, tx, rx);
|
||||
size_t len = strlen(stat);
|
||||
|
||||
if (send(sock, stat, len, 0) == -1) {
|
||||
ERROR("[android] send");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char ret = 0;
|
||||
|
||||
if (recv(sock, &ret, 1, 0) == -1) {
|
||||
ERROR("[android] recv");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ void free_udprelay(void);
|
||||
|
||||
#ifdef ANDROID
|
||||
int protect_socket(int fd);
|
||||
int send_traffic_stat(uint64_t tx, uint64_t rx);
|
||||
#endif
|
||||
|
||||
#endif // _COMMON_H
|
||||
|
||||
+29
-6
@@ -82,6 +82,9 @@
|
||||
int verbose = 0;
|
||||
#ifdef ANDROID
|
||||
int vpn = 0;
|
||||
uint64_t tx = 0;
|
||||
uint64_t rx = 0;
|
||||
ev_timer stat_timer;
|
||||
#endif
|
||||
|
||||
static int acl = 0;
|
||||
@@ -250,6 +253,9 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
|
||||
// insert shadowsocks header
|
||||
if (!remote->direct) {
|
||||
#ifdef ANDROID
|
||||
tx += r;
|
||||
#endif
|
||||
remote->buf = ss_encrypt(BUF_SIZE, remote->buf, &r,
|
||||
server->e_ctx);
|
||||
|
||||
@@ -571,11 +577,19 @@ static void server_send_cb(EV_P_ ev_io *w, int revents)
|
||||
server->buf_idx = 0;
|
||||
ev_io_stop(EV_A_ & server_send_ctx->io);
|
||||
ev_io_start(EV_A_ & remote->recv_ctx->io);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
static void stat_update_cb(EV_P_ ev_timer *watcher, int revents)
|
||||
{
|
||||
send_traffic_stat(tx, rx);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents)
|
||||
{
|
||||
struct remote_ctx *remote_ctx = (struct remote_ctx *)(((void *)watcher)
|
||||
@@ -620,6 +634,9 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
}
|
||||
|
||||
if (!remote->direct) {
|
||||
#ifdef ANDROID
|
||||
rx += r;
|
||||
#endif
|
||||
server->buf = ss_decrypt(BUF_SIZE, server->buf, &r, server->d_ctx);
|
||||
if (server->buf == NULL) {
|
||||
LOGE("invalid password or cipher");
|
||||
@@ -733,13 +750,9 @@ static struct remote * new_remote(int fd, int timeout)
|
||||
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_timer_init(&remote->send_ctx->watcher, remote_timeout_cb,
|
||||
min(MAX_CONNECT_TIMEOUT,
|
||||
timeout),
|
||||
0);
|
||||
min(MAX_CONNECT_TIMEOUT, timeout), 0);
|
||||
ev_timer_init(&remote->recv_ctx->watcher, remote_timeout_cb,
|
||||
min(MAX_CONNECT_TIMEOUT,
|
||||
timeout),
|
||||
timeout);
|
||||
min(MAX_CONNECT_TIMEOUT, timeout), timeout);
|
||||
remote->recv_ctx->remote = remote;
|
||||
remote->send_ctx->remote = remote;
|
||||
return remote;
|
||||
@@ -1141,6 +1154,11 @@ int main(int argc, char **argv)
|
||||
|
||||
struct ev_loop *loop = EV_DEFAULT;
|
||||
|
||||
#ifdef ANDROID
|
||||
ev_timer_init(&stat_timer, stat_update_cb, 1, 1);
|
||||
ev_timer_start(loop, stat_timer);
|
||||
#endif
|
||||
|
||||
// Setup socket
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(local_addr, local_port);
|
||||
@@ -1182,6 +1200,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Clean up
|
||||
|
||||
#ifdef ANDROID
|
||||
ev_timer_stop(loop, stat_timer);
|
||||
#endif
|
||||
|
||||
ev_io_stop(loop, &listen_ctx.io);
|
||||
free_connections(loop);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user