Browse Source

refine library interface

pull/140/head
Max Lv 10 years ago
parent
commit
86087825a9
5 changed files with 183 additions and 12 deletions
  1. 1
      src/Makefile.am
  2. 5
      src/acl.c
  3. 133
      src/local.c
  4. 24
      src/shadowsocks.h
  5. 32
      src/utils.h

1
src/Makefile.am

@ -71,5 +71,6 @@ lib_LTLIBRARIES = libshadowsocks.la
libshadowsocks_la_SOURCES = $(ss_local_SOURCES) libshadowsocks_la_SOURCES = $(ss_local_SOURCES)
libshadowsocks_la_CFLAGS = $(ss_local_CFLAGS) -DLIB_ONLY libshadowsocks_la_CFLAGS = $(ss_local_CFLAGS) -DLIB_ONLY
libshadowsocks_la_LIBADD = $(ss_local_LDADD) libshadowsocks_la_LIBADD = $(ss_local_LDADD)
include_HEADERS = src/shadowsocks.h
endif endif

5
src/acl.c

@ -69,7 +69,10 @@ int init_acl(const char *path)
cork_string_array_init(&acl_domain_array); cork_string_array_init(&acl_domain_array);
FILE *f = fopen(path, "r"); FILE *f = fopen(path, "r");
if (f == NULL) FATAL("Invalid acl path.");
if (f == NULL) {
LOGE("Invalid acl path.");
return -1;
}
char line[256]; char line[256];
while(!feof(f)) while(!feof(f))

133
src/local.c

@ -43,6 +43,11 @@
#include "config.h" #include "config.h"
#endif #endif
#ifdef LIB_ONLY
#include <pthread.h>
#include "shadowsocks.h"
#endif
#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) && defined(__linux__) #if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H) && defined(__linux__)
#include <net/if.h> #include <net/if.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -986,8 +991,7 @@ int main (int argc, char **argv)
else if (option_index == 1) else if (option_index == 1)
{ {
LOGD("initialize acl..."); LOGD("initialize acl...");
acl = 1;
init_acl(optarg);
acl = !init_acl(optarg);
} }
break; break;
case 's': case 's':
@ -1160,5 +1164,130 @@ int main (int argc, char **argv)
return 0; 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 #endif

24
src/shadowsocks.h

@ -23,21 +23,29 @@
#define _SHADOWSOCKS_H #define _SHADOWSOCKS_H
typedef struct { 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 *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 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 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 int verbose; // verbose mode
} profile_t; } profile_t;
// create and start a shadowsocks service, // create and start a shadowsocks service,
// if success, return the pid.
// if success, return the tid.
// if not, return -1 // 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 #endif // _SHADOWSOCKS_H

32
src/utils.h

@ -42,7 +42,37 @@
#define STR(x) #x #define STR(x) #x
#define TOSTR(x) STR(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" #define TIME_FORMAT "%Y-%m-%d %H:%M:%S"

Loading…
Cancel
Save