From 2f12f5bf92fa7bc78b057666ecfa89cafe9c13b2 Mon Sep 17 00:00:00 2001 From: hev Date: Sun, 9 Jun 2024 20:12:11 +0800 Subject: [PATCH] Android: Build as a shared library. --- Android.mk | 6 +- Application.mk | 2 +- README.md | 41 +++++++++++++ src/hev-config.c | 32 +++++++++- src/hev-config.h | 8 ++- src/hev-jni.c | 130 +++++++++++++++++++++++++++++++++++++++++ src/hev-jni.h | 13 +++++ src/hev-main.c | 87 ++++++++++++++++++++------- src/hev-main.h | 49 +++++++++++++++- src/hev-socks5-proxy.c | 34 +++++------ src/hev-socks5-proxy.h | 1 + 11 files changed, 354 insertions(+), 49 deletions(-) create mode 100644 src/hev-jni.c create mode 100644 src/hev-jni.h diff --git a/Android.mk b/Android.mk index f4fe9c4e7..e4a93e9d4 100644 --- a/Android.mk +++ b/Android.mk @@ -1,4 +1,4 @@ -# Copyright (C) 2021 The Android Open Source Project +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -32,11 +32,11 @@ LOCAL_SRC_FILES := $(patsubst $(SRCDIR)/%,src/%,$(SRCFILES)) LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/src/misc \ $(LOCAL_PATH)/src/core/include \ - $(LOCAL_PATH)/third-part/yaml/src \ + $(LOCAL_PATH)/third-part/yaml/include \ $(LOCAL_PATH)/third-part/hev-task-system/include LOCAL_CFLAGS += $(VERSION_CFLAGS) ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) LOCAL_CFLAGS += -mfpu=neon endif LOCAL_STATIC_LIBRARIES := yaml hev-task-system -include $(BUILD_EXECUTABLE) +include $(BUILD_SHARED_LIBRARY) diff --git a/Application.mk b/Application.mk index 002f57403..2f2a56dc9 100644 --- a/Application.mk +++ b/Application.mk @@ -1,4 +1,4 @@ -# Copyright (C) 2020 The Android Open Source Project +# Copyright (C) 2024 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index b531608ae..4099fe1d0 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,47 @@ jerry pass 1a iptables -A OUTPUT -p tcp --syn -m mark --mark 0x1a -m connlimit --connlimit-above 2 -j REJECT ``` +## API + +```c +/** + * hev_socks5_server_main_from_file: + * @config_path: config file path + * + * Start and run the socks5 server, this function will blocks until the + * hev_socks5_server_quit is called or an error occurs. + * + * Returns: returns zero on successful, otherwise returns -1. + * + * Since: 2.6.7 + */ +int hev_socks5_server_main_from_file (const char *config_path); + +/** + * hev_socks5_server_main_from_str: + * @config_str: string config + * @config_len: the byte length of string config + * + * Start and run the socks5 server, this function will blocks until the + * hev_socks5_server_quit is called or an error occurs. + * + * Returns: returns zero on successful, otherwise returns -1. + * + * Since: 2.6.7 + */ +int hev_socks5_server_main_from_str (const unsigned char *config_str, + unsigned int config_len); + +/** + * hev_socks5_server_quit: + * + * Stop the socks5 server. + * + * Since: 2.6.7 + */ +void hev_socks5_server_quit (void); +``` + ## Contributors * **Ammar Faizi** - https://github.com/ammarfaizi2 diff --git a/src/hev-config.c b/src/hev-config.c index ca149fb6c..b0743e774 100644 --- a/src/hev-config.c +++ b/src/hev-config.c @@ -1,8 +1,8 @@ /* ============================================================================ Name : hev-config.c - Author : Heiher - Copyright : Copyright (c) 2017 - 2023 hev + Author : hev + Copyright : Copyright (c) 2017 - 2024 hev Description : Config ============================================================================ */ @@ -276,7 +276,7 @@ hev_config_parse_doc (yaml_document_t *doc) } int -hev_config_init (const char *path) +hev_config_init_from_file (const char *path) { yaml_parser_t parser; yaml_document_t doc; @@ -309,6 +309,32 @@ hev_config_init (const char *path) return res; } +int +hev_config_init_from_str (const unsigned char *config_str, + unsigned int config_len) +{ + yaml_parser_t parser; + yaml_document_t doc; + int res = -1; + + if (!yaml_parser_initialize (&parser)) + goto exit; + + yaml_parser_set_input_string (&parser, config_str, config_len); + if (!yaml_parser_load (&parser, &doc)) { + fprintf (stderr, "Failed to parse config."); + goto exit_free_parser; + } + + res = hev_config_parse_doc (&doc); + yaml_document_delete (&doc); + +exit_free_parser: + yaml_parser_delete (&parser); +exit: + return res; +} + void hev_config_fini (void) { diff --git a/src/hev-config.h b/src/hev-config.h index 58d2fab59..0b340b5ee 100644 --- a/src/hev-config.h +++ b/src/hev-config.h @@ -1,8 +1,8 @@ /* ============================================================================ Name : hev-config.h - Author : Heiher - Copyright : Copyright (c) 2017 - 2022 hev + Author : hev + Copyright : Copyright (c) 2017 - 2024 hev Description : Config ============================================================================ */ @@ -10,7 +10,9 @@ #ifndef __HEV_CONFIG_H__ #define __HEV_CONFIG_H__ -int hev_config_init (const char *path); +int hev_config_init_from_file (const char *config_path); +int hev_config_init_from_str (const unsigned char *config_str, + unsigned int config_len); void hev_config_fini (void); unsigned int hev_config_get_workers (void); diff --git a/src/hev-jni.c b/src/hev-jni.c new file mode 100644 index 000000000..d1b6e5a9d --- /dev/null +++ b/src/hev-jni.c @@ -0,0 +1,130 @@ +/* + ============================================================================ + Name : hev-jni.c + Author : hev + Copyright : Copyright (c) 2019 - 2024 hev + Description : Jave Native Interface + ============================================================================ + */ + +#ifdef ANDROID + +#include +#include + +#include +#include +#include +#include + +#include "hev-main.h" + +#include "hev-jni.h" + +/* clang-format off */ +#ifndef PKGNAME +#define PKGNAME hev/socks5 +#endif +/* clang-format on */ + +#define STR(s) STR_ARG (s) +#define STR_ARG(c) #c +#define N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) + +typedef struct _ThreadData ThreadData; + +struct _ThreadData +{ + char *path; +}; + +static JavaVM *java_vm; +static pthread_t work_thread; +static pthread_mutex_t mutex; +static pthread_key_t current_jni_env; + +static void native_start_service (JNIEnv *env, jobject thiz, + jstring config_path); +static void native_stop_service (JNIEnv *env, jobject thiz); + +static JNINativeMethod native_methods[] = { + { "Socks5StartService", "(Ljava/lang/String;)V", + (void *)native_start_service }, + { "Socks5StopService", "()V", (void *)native_stop_service }, +}; + +static void +detach_current_thread (void *env) +{ + (*java_vm)->DetachCurrentThread (java_vm); +} + +jint +JNI_OnLoad (JavaVM *vm, void *reserved) +{ + JNIEnv *env = NULL; + jclass klass; + + java_vm = vm; + if (JNI_OK != (*vm)->GetEnv (vm, (void **)&env, JNI_VERSION_1_4)) { + return 0; + } + + klass = (*env)->FindClass (env, STR (PKGNAME) "/Socks5Service"); + (*env)->RegisterNatives (env, klass, native_methods, + N_ELEMENTS (native_methods)); + (*env)->DeleteLocalRef (env, klass); + + pthread_key_create (¤t_jni_env, detach_current_thread); + pthread_mutex_init (&mutex, NULL); + + return JNI_VERSION_1_4; +} + +static void * +thread_handler (void *data) +{ + ThreadData *tdata = data; + + hev_socks5_server_main_from_file (tdata->path); + + free (tdata->path); + free (tdata); + + return NULL; +} + +static void +native_start_service (JNIEnv *env, jobject thiz, jstring config_path) +{ + const jbyte *bytes; + ThreadData *tdata; + + pthread_mutex_lock (&mutex); + if (work_thread) + return; + + tdata = malloc (sizeof (ThreadData)); + + bytes = (const jbyte *)(*env)->GetStringUTFChars (env, config_path, NULL); + tdata->path = strdup ((const char *)bytes); + (*env)->ReleaseStringUTFChars (env, config_path, (const char *)bytes); + + pthread_create (&work_thread, NULL, thread_handler, tdata); + pthread_mutex_unlock (&mutex); +} + +static void +native_stop_service (JNIEnv *env, jobject thiz) +{ + pthread_mutex_lock (&mutex); + if (!work_thread) + return; + + hev_socks5_server_quit (); + pthread_join (work_thread, NULL); + work_thread = 0; + pthread_mutex_unlock (&mutex); +} + +#endif /* ANDROID */ diff --git a/src/hev-jni.h b/src/hev-jni.h new file mode 100644 index 000000000..8674fabd9 --- /dev/null +++ b/src/hev-jni.h @@ -0,0 +1,13 @@ +/* + ============================================================================ + Name : hev-jni.h + Author : hev + Copyright : Copyright (c) 2019 - 2024 hev + Description : Java Native Interface + ============================================================================ + */ + +#ifndef __HEV_JNI_H__ +#define __HEV_JNI_H__ + +#endif /* __HEV_JNI_H__ */ diff --git a/src/hev-main.c b/src/hev-main.c index c7d7c055c..533151700 100644 --- a/src/hev-main.c +++ b/src/hev-main.c @@ -1,13 +1,15 @@ /* ============================================================================ Name : hev-main.c - Author : Heiher + Author : hev Copyright : Copyright (c) 2017 - 2024 hev Description : Main ============================================================================ */ #include +#include +#include #include #include @@ -21,6 +23,8 @@ #include "hev-main.h" +#define WEAK __attribute__ ((weak)) + static void show_help (const char *self_path) { @@ -29,8 +33,14 @@ show_help (const char *self_path) MICRO_VERSION, COMMIT_ID); } -int -main (int argc, char *argv[]) +static void +sigint_handler (int signum) +{ + hev_socks5_proxy_stop (); +} + +static int +hev_socks5_server_main_inner (void) { const char *pid_file; const char *log_file; @@ -38,15 +48,6 @@ main (int argc, char *argv[]) int nofile; int res; - if (argc != 2) { - show_help (argv[0]); - return -1; - } - - res = hev_config_init (argv[1]); - if (res < 0) - return -2; - log_file = hev_config_get_misc_log_file (); log_level = hev_config_get_misc_log_level (); @@ -58,11 +59,16 @@ main (int argc, char *argv[]) res = hev_logger_init (log_level, log_file); if (res < 0) - return -3; + return -2; res = hev_socks5_logger_init (log_level, log_file); if (res < 0) - return -4; + return -3; + + nofile = hev_config_get_misc_limit_nofile (); + res = set_limit_nofile (nofile); + if (res < 0) + LOG_W ("set limit nofile"); pid_file = hev_config_get_misc_pid_file (); if (pid_file) @@ -70,12 +76,7 @@ main (int argc, char *argv[]) res = hev_socks5_proxy_init (); if (res < 0) - return -5; - - nofile = hev_config_get_misc_limit_nofile (); - res = set_limit_nofile (nofile); - if (res < 0) - LOG_W ("set limit nofile"); + return -4; hev_socks5_proxy_run (); @@ -86,3 +87,49 @@ main (int argc, char *argv[]) return 0; } + +int +hev_socks5_server_main_from_file (const char *config_path) +{ + int res = hev_config_init_from_file (config_path); + if (res < 0) + return -1; + + return hev_socks5_server_main_inner (); +} + +int +hev_socks5_server_main_from_str (const unsigned char *config_str, + unsigned int config_len) +{ + int res = hev_config_init_from_str (config_str, config_len); + if (res < 0) + return -1; + + return hev_socks5_server_main_inner (); +} + +void +hev_socks5_server_quit (void) +{ + hev_socks5_proxy_stop (); +} + +WEAK int +main (int argc, char *argv[]) +{ + int res; + + if (argc < 2 || strcmp (argv[1], "--version") == 0) { + show_help (argv[0]); + return -1; + } + + signal (SIGINT, sigint_handler); + + res = hev_socks5_server_main_from_file (argv[1]); + if (res < 0) + return -2; + + return 0; +} diff --git a/src/hev-main.h b/src/hev-main.h index 071796690..37a3c8ce0 100644 --- a/src/hev-main.h +++ b/src/hev-main.h @@ -1,8 +1,8 @@ /* ============================================================================ Name : hev-main.h - Author : Heiher - Copyright : Copyright (c) 2017 - 2021 hev + Author : hev + Copyright : Copyright (c) 2017 - 2024 hev Description : Main ============================================================================ */ @@ -10,4 +10,49 @@ #ifndef __HEV_MAIN_H__ #define __HEV_MAIN_H__ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * hev_socks5_server_main_from_file: + * @config_path: config file path + * + * Start and run the socks5 server, this function will blocks until the + * hev_socks5_server_quit is called or an error occurs. + * + * Returns: returns zero on successful, otherwise returns -1. + * + * Since: 2.6.7 + */ +int hev_socks5_server_main_from_file (const char *config_path); + +/** + * hev_socks5_server_main_from_str: + * @config_str: string config + * @config_len: the byte length of string config + * + * Start and run the socks5 server, this function will blocks until the + * hev_socks5_server_quit is called or an error occurs. + * + * Returns: returns zero on successful, otherwise returns -1. + * + * Since: 2.6.7 + */ +int hev_socks5_server_main_from_str (const unsigned char *config_str, + unsigned int config_len); + +/** + * hev_socks5_server_quit: + * + * Stop the socks5 server. + * + * Since: 2.6.7 + */ +void hev_socks5_server_quit (void); + +#ifdef __cplusplus +} +#endif + #endif /* __HEV_MAIN_H__ */ diff --git a/src/hev-socks5-proxy.c b/src/hev-socks5-proxy.c index 620965436..fe41d2b03 100644 --- a/src/hev-socks5-proxy.c +++ b/src/hev-socks5-proxy.c @@ -122,22 +122,7 @@ hev_socks5_proxy_load (void) static void sigint_handler (int signum) { - int i; - - if (signum == SIGUSR1) { - hev_socks5_proxy_load (); - return; - } - - for (i = 0; i < workers; i++) { - HevSocks5Worker *worker; - - worker = worker_list[i]; - if (!worker) - continue; - - hev_socks5_worker_stop (worker); - } + hev_socks5_proxy_load (); } int @@ -178,7 +163,6 @@ hev_socks5_proxy_init (void) } signal (SIGPIPE, SIG_IGN); - signal (SIGINT, sigint_handler); signal (SIGUSR1, sigint_handler); return 0; @@ -307,3 +291,19 @@ hev_socks5_proxy_run (void) worker_list[0] = NULL; } } + +void +hev_socks5_proxy_stop (void) +{ + int i; + + for (i = 0; i < workers; i++) { + HevSocks5Worker *worker; + + worker = worker_list[i]; + if (!worker) + continue; + + hev_socks5_worker_stop (worker); + } +} diff --git a/src/hev-socks5-proxy.h b/src/hev-socks5-proxy.h index 3f962b708..d94ebeaf6 100644 --- a/src/hev-socks5-proxy.h +++ b/src/hev-socks5-proxy.h @@ -14,5 +14,6 @@ int hev_socks5_proxy_init (void); void hev_socks5_proxy_fini (void); void hev_socks5_proxy_run (void); +void hev_socks5_proxy_stop (void); #endif /* __HEV_SOCKS5_PROXY_H__ */