Browse Source

add traffic stat IPC calls

pull/465/head
Max Lv 9 years ago
parent
commit
c9e0cb6698
3 changed files with 83 additions and 9 deletions
  1. 56
      src/android.c
  2. 1
      src/common.h
  3. 35
      src/local.c

56
src/android.c

@ -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;
}

1
src/common.h

@ -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

35
src/local.c

@ -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);

Loading…
Cancel
Save