mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-28 19:53:46 +00:00
refine library interface
This commit is contained in:
@@ -71,5 +71,6 @@ lib_LTLIBRARIES = libshadowsocks.la
|
||||
libshadowsocks_la_SOURCES = $(ss_local_SOURCES)
|
||||
libshadowsocks_la_CFLAGS = $(ss_local_CFLAGS) -DLIB_ONLY
|
||||
libshadowsocks_la_LIBADD = $(ss_local_LDADD)
|
||||
include_HEADERS = src/shadowsocks.h
|
||||
endif
|
||||
|
||||
|
||||
@@ -69,7 +69,10 @@ int init_acl(const char *path)
|
||||
cork_string_array_init(&acl_domain_array);
|
||||
|
||||
FILE *f = fopen(path, "r");
|
||||
if (f == NULL) FATAL("Invalid acl path.");
|
||||
if (f == NULL) {
|
||||
LOGE("Invalid acl path.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char line[256];
|
||||
while(!feof(f))
|
||||
|
||||
+131
-2
@@ -43,6 +43,11 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef LIB_ONLY
|
||||
#include <pthread.h>
|
||||
#include "shadowsocks.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) && defined(__linux__)
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -986,8 +991,7 @@ int main (int argc, char **argv)
|
||||
else if (option_index == 1)
|
||||
{
|
||||
LOGD("initialize acl...");
|
||||
acl = 1;
|
||||
init_acl(optarg);
|
||||
acl = !init_acl(optarg);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
@@ -1160,5 +1164,130 @@ int main (int argc, char **argv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
static int running = 0;
|
||||
static pthread_t worker_tid;
|
||||
|
||||
static void *
|
||||
start_worker(void *arg)
|
||||
{
|
||||
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;
|
||||
char *password = profile.password;
|
||||
char *log = profile.log;
|
||||
int remote_port = profile.remote_port;
|
||||
int local_port = profile.local_port;
|
||||
int timeout = profile.timeout;
|
||||
|
||||
udprelay = profile.udp_relay;
|
||||
fast_open = profile.fast_open;
|
||||
verbose = profile.verbose;
|
||||
|
||||
char local_port_str[16];
|
||||
char remote_port_str[16];
|
||||
sprintf(local_port_str, "%d", local_port);
|
||||
sprintf(remote_port_str, "%d", remote_port);
|
||||
|
||||
if (profile.acl != NULL)
|
||||
{
|
||||
acl = !init_acl(profile.acl);
|
||||
}
|
||||
|
||||
if (local_addr == NULL) local_addr = "0.0.0.0";
|
||||
|
||||
USE_LOGFILE(log);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_init();
|
||||
#else
|
||||
// ignore SIGPIPE
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGABRT, SIG_IGN);
|
||||
#endif
|
||||
|
||||
// Setup keys
|
||||
LOGD("initialize ciphers... %s", method);
|
||||
int m = enc_init(password, method);
|
||||
|
||||
// Setup socket
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(local_addr, local_port_str);
|
||||
if (listenfd < 0)
|
||||
{
|
||||
FATAL("bind() error..");
|
||||
}
|
||||
if (listen(listenfd, SOMAXCONN) == -1)
|
||||
{
|
||||
FATAL("listen() error.");
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
LOGD("server listening at port %s.", local_port_str);
|
||||
|
||||
// Setup proxy context
|
||||
struct listen_ctx listen_ctx;
|
||||
|
||||
listen_ctx.remote_num = 1;
|
||||
listen_ctx.remote_addr = malloc(sizeof(ss_addr_t));
|
||||
listen_ctx.remote_addr[0].host = remote_host;
|
||||
listen_ctx.remote_addr[0].port = remote_port_str;
|
||||
listen_ctx.timeout = timeout;
|
||||
listen_ctx.fd = listenfd;
|
||||
listen_ctx.method = m;
|
||||
listen_ctx.iface = NULL;
|
||||
|
||||
struct ev_loop *loop = ev_default_loop(0);
|
||||
if (!loop)
|
||||
{
|
||||
FATAL("ev_loop error.");
|
||||
}
|
||||
ev_io_init (&listen_ctx.io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start (loop, &listen_ctx.io);
|
||||
|
||||
// Setup UDP
|
||||
if (udprelay)
|
||||
{
|
||||
LOGD("udprelay enabled.");
|
||||
udprelay_init(local_addr, local_port_str, remote_host, remote_port_str, m, listen_ctx.timeout, NULL);
|
||||
}
|
||||
|
||||
ev_run (loop, 0);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_cleanup();
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
|
||||
+16
-8
@@ -23,21 +23,29 @@
|
||||
#define _SHADOWSOCKS_H
|
||||
|
||||
typedef struct {
|
||||
char *server; // server hostname or ip
|
||||
char *remote_host; // hostname or ip of remote server
|
||||
char *local_addr; // local ip to bind
|
||||
char *method; // encryption method
|
||||
char *passwd; // password of server
|
||||
char *config; // file path to config
|
||||
char *password; // password of remote server
|
||||
char *acl; // file path to acl
|
||||
int server_port; // port number of server
|
||||
int local_port; // port number of local
|
||||
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
|
||||
int fast_open; // tcp fast open
|
||||
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 pid.
|
||||
// if success, return the tid.
|
||||
// if not, return -1
|
||||
int create_ss_service (profile_t profile, char *log_file);
|
||||
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);
|
||||
|
||||
#endif // _SHADOWSOCKS_H
|
||||
|
||||
+31
-1
@@ -42,7 +42,37 @@
|
||||
#define STR(x) #x
|
||||
#define TOSTR(x) STR(x)
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef LIB_ONLY
|
||||
|
||||
#define TIME_FORMAT "%Y-%m-%d %H:%M:%S"
|
||||
|
||||
#define USE_SYSLOG(ident)
|
||||
|
||||
FILE *logfile;
|
||||
|
||||
#define USE_LOGFILE(ident) do {\
|
||||
if (ident != NULL) logfile = fopen(ident, "w+");}\
|
||||
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__);}\
|
||||
}\
|
||||
while(0)
|
||||
|
||||
#define LOGE(format, ...) do {\
|
||||
if (logfile != NULL) {\
|
||||
time_t now = time(NULL);\
|
||||
char timestr[20];\
|
||||
strftime(timestr, 20, TIME_FORMAT, localtime(&now));\
|
||||
fprintf(logfile, " %s ERROR: " format "\n", timestr, ##__VA_ARGS__);}\
|
||||
}\
|
||||
while(0)
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
#define TIME_FORMAT "%Y-%m-%d %H:%M:%S"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user