mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-25 10:13:44 +00:00
fix #128
This commit is contained in:
+31
-35
@@ -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
|
||||
|
||||
|
||||
+31
-10
@@ -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
|
||||
|
||||
+8
-2
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user