/* * android.c - Setup IPC for shadowsocks-android * * Copyright (C) 2013 - 2015, Max Lv * * This file is part of the shadowsocks-libev. * * shadowsocks-libev is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * shadowsocks-libev is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with shadowsocks-libev; see the file COPYING. If not, see * . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "netutils.h" #include "utils.h" int protect_socket(int fd) { 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/protect_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; } if (ancil_send_fd(sock, fd)) { ERROR("[android] ancil_send_fd"); 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; } 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, "%llu|%llu", 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; }