From 1008cf1f5bb0004c64a86b103c157ec98c177cd6 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Mon, 3 Nov 2014 17:04:40 +0800 Subject: [PATCH] fix #128 --- src/local.c | 66 ++++++++++++++++++++++------------------------- src/shadowsocks.h | 41 ++++++++++++++++++++++------- src/utils.h | 10 +++++-- 3 files changed, 70 insertions(+), 47 deletions(-) diff --git a/src/local.c b/src/local.c index d7f80a36..b97744a5 100644 --- a/src/local.c +++ b/src/local.c @@ -1166,15 +1166,35 @@ int main (int argc, char **argv) } #else -static int running = 0; -static pthread_t worker_tid; - -static void * -start_worker(void *arg) +int start_ss_service(profile_t profile) { + +#ifndef __MINGW32__ + /* Our process ID and Session ID */ + pid_t pid; + + /* Fork off the parent process */ + pid = fork(); + if (pid < 0) + { + return -1; + } + + /* If we got a good PID, then + we can exit the parent process. */ + if (pid > 0) + { + return pid; + } + + /* Close out the standard file descriptors */ + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); +#endif + srand(time(NULL)); - profile_t profile = *((profile_t *)arg); char *remote_host = profile.remote_host; char *local_addr = profile.local_addr; char *method = profile.method; @@ -1193,6 +1213,8 @@ start_worker(void *arg) sprintf(local_port_str, "%d", local_port); sprintf(remote_port_str, "%d", remote_port); + USE_LOGFILE(log); + if (profile.acl != NULL) { acl = !init_acl(profile.acl); @@ -1200,8 +1222,6 @@ start_worker(void *arg) if (local_addr == NULL) local_addr = "0.0.0.0"; - USE_LOGFILE(log); - #ifdef __MINGW32__ winsock_init(); #else @@ -1219,11 +1239,11 @@ start_worker(void *arg) listenfd = create_and_bind(local_addr, local_port_str); if (listenfd < 0) { - FATAL("bind() error.."); + FATAL("bind()"); } if (listen(listenfd, SOMAXCONN) == -1) { - FATAL("listen() error."); + FATAL("listen()"); } setnonblocking(listenfd); LOGD("server listening at port %s.", local_port_str); @@ -1261,33 +1281,9 @@ start_worker(void *arg) winsock_cleanup(); #endif + // cannot reach here return 0; } -void stop_ss_service(int blocking) -{ - if (running) { - struct ev_loop *loop = ev_default_loop(0); - ev_break(loop, EVBREAK_ALL); - if (blocking) - { - pthread_join(worker_tid, NULL); - } - } -} - -int start_ss_service(profile_t profile) -{ - pthread_attr_t attr; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - - int err = pthread_create(&worker_tid, NULL, start_worker, &profile); - - if (err) return -1; - return 0; - -} #endif diff --git a/src/shadowsocks.h b/src/shadowsocks.h index 7a802c4d..c157da47 100644 --- a/src/shadowsocks.h +++ b/src/shadowsocks.h @@ -23,29 +23,50 @@ #define _SHADOWSOCKS_H typedef struct { + /* Required */ char *remote_host; // hostname or ip of remote server char *local_addr; // local ip to bind char *method; // encryption method char *password; // password of remote server - char *acl; // file path to acl - char *log; // file path to log int remote_port; // port number of remote server int local_port; // port number of local server int timeout; // connection timeout + + /* Optional, set NULL if not valid */ + char *acl; // file path to acl + char *log; // file path to log int fast_open; // enable tcp fast open int udp_relay; // enable udp relay int verbose; // verbose mode } profile_t; -// create and start a shadowsocks service, -// if success, return the tid. -// if not, return -1 +/* + * An example profile + +const profile_t EXAMPLE_PROFILE = { + .remote_host = "example.com", + .local_addr = "127.0.0.1", + .method = "bf-cfb", + .password = "barfoo!", + .remote_port = 8338, + .local_port = 1080, + + .acl = NULL, + .log = NULL, + .fast_open = 0, + .udp_relay = 0, + .verbose = 0 +}; + +*/ + +// Create and start a shadowsocks service, +// If success, return the pid, if not, return -1 +// On win32, this function won't return, +// you have to call it in on other processes int start_ss_service(profile_t profile); -// stop the current shadowsocks service, -// if blocking set true, this call will be blocked until no events left. -// call this function in blocking mode would take quite long time, depends on -// the timeout you set. -void stop_ss_service(int blocking); +// To stop the service on posix system, just kill the daemon process +// kill(pid, SIGKILL); #endif // _SHADOWSOCKS_H diff --git a/src/utils.h b/src/utils.h index 5be61dbd..e90e5f3c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -54,12 +54,17 @@ FILE *logfile; if (ident != NULL) logfile = fopen(ident, "w+");}\ while(0) +#define CLOSE_LOGFILE do {\ + if (logfile != NULL) fclose(logfile);}\ +while(0) + #define LOGD(format, ...) do {\ if (logfile != NULL) {\ time_t now = time(NULL);\ char timestr[20];\ strftime(timestr, 20, TIME_FORMAT, localtime(&now));\ - fprintf(logfile, " %s INFO: " format "\n", timestr, ##__VA_ARGS__);}\ + fprintf(logfile, " %s INFO: " format "\n", timestr, ##__VA_ARGS__);\ + fflush(logfile);}\ }\ while(0) @@ -68,7 +73,8 @@ while(0) time_t now = time(NULL);\ char timestr[20];\ strftime(timestr, 20, TIME_FORMAT, localtime(&now));\ - fprintf(logfile, " %s ERROR: " format "\n", timestr, ##__VA_ARGS__);}\ + fprintf(logfile, " %s ERROR: " format "\n", timestr, ##__VA_ARGS__);\ + fflush(logfile);}\ }\ while(0)