mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-30 13:13:44 +00:00
handle sigterm and sigkill
This commit is contained in:
@@ -69,7 +69,8 @@ int init_acl(const char *path)
|
||||
cork_string_array_init(&acl_domain_array);
|
||||
|
||||
FILE *f = fopen(path, "r");
|
||||
if (f == NULL) {
|
||||
if (f == NULL)
|
||||
{
|
||||
LOGE("Invalid acl path.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* include.h - Provide global definitions
|
||||
* common.h - Provide global definitions
|
||||
*
|
||||
* Copyright (C) 2013 - 2014, Max Lv <max.c.lv@gmail.com>
|
||||
*
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
int udprelay_init(const char *server_host, const char *server_port,
|
||||
int init_udprelay(const char *server_host, const char *server_port,
|
||||
#ifdef UDPRELAY_LOCAL
|
||||
const char *remote_host, const char *remote_port,
|
||||
#ifdef UDPRELAY_TUNNEL
|
||||
@@ -49,4 +49,6 @@ int udprelay_init(const char *server_host, const char *server_port,
|
||||
#endif
|
||||
int method, int timeout, const char *iface);
|
||||
|
||||
void free_udprelay(void);
|
||||
|
||||
#endif // _INCLUDE_H
|
||||
+2
-2
@@ -392,10 +392,10 @@ json_value * json_parse_ex (json_settings * settings,
|
||||
else
|
||||
{
|
||||
top->u.object.values [top->u.object.length].name
|
||||
= (json_char *) top->_reserved.object_mem;
|
||||
= (json_char *) top->_reserved.object_mem;
|
||||
|
||||
top->u.object.values [top->u.object.length].name_length
|
||||
= string_length;
|
||||
= string_length;
|
||||
|
||||
(*(json_char **) &top->_reserved.object_mem) += string_length + 1;
|
||||
}
|
||||
|
||||
+159
-159
@@ -54,216 +54,216 @@ extern "C"
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long max_memory;
|
||||
int settings;
|
||||
typedef struct
|
||||
{
|
||||
unsigned long max_memory;
|
||||
int settings;
|
||||
|
||||
/* Custom allocator support (leave null to use malloc/free)
|
||||
*/
|
||||
/* Custom allocator support (leave null to use malloc/free)
|
||||
*/
|
||||
|
||||
void * (* mem_alloc) (size_t, int zero, void * user_data);
|
||||
void (* mem_free) (void *, void * user_data);
|
||||
void * (* mem_alloc) (size_t, int zero, void * user_data);
|
||||
void (* mem_free) (void *, void * user_data);
|
||||
|
||||
void * user_data; /* will be passed to mem_alloc and mem_free */
|
||||
void * user_data; /* will be passed to mem_alloc and mem_free */
|
||||
|
||||
} json_settings;
|
||||
} json_settings;
|
||||
|
||||
#define json_enable_comments 0x01
|
||||
|
||||
typedef enum
|
||||
{
|
||||
json_none,
|
||||
json_object,
|
||||
json_array,
|
||||
json_integer,
|
||||
json_double,
|
||||
json_string,
|
||||
json_boolean,
|
||||
json_null
|
||||
|
||||
} json_type;
|
||||
|
||||
extern const struct _json_value json_value_none;
|
||||
|
||||
typedef struct _json_value
|
||||
{
|
||||
struct _json_value * parent;
|
||||
|
||||
json_type type;
|
||||
|
||||
union
|
||||
typedef enum
|
||||
{
|
||||
int boolean;
|
||||
json_int_t integer;
|
||||
double dbl;
|
||||
json_none,
|
||||
json_object,
|
||||
json_array,
|
||||
json_integer,
|
||||
json_double,
|
||||
json_string,
|
||||
json_boolean,
|
||||
json_null
|
||||
|
||||
struct
|
||||
} json_type;
|
||||
|
||||
extern const struct _json_value json_value_none;
|
||||
|
||||
typedef struct _json_value
|
||||
{
|
||||
struct _json_value * parent;
|
||||
|
||||
json_type type;
|
||||
|
||||
union
|
||||
{
|
||||
unsigned int length;
|
||||
json_char * ptr; /* null terminated */
|
||||
|
||||
} string;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned int length;
|
||||
int boolean;
|
||||
json_int_t integer;
|
||||
double dbl;
|
||||
|
||||
struct
|
||||
{
|
||||
json_char * name;
|
||||
unsigned int name_length;
|
||||
unsigned int length;
|
||||
json_char * ptr; /* null terminated */
|
||||
|
||||
struct _json_value * value;
|
||||
} string;
|
||||
|
||||
} * values;
|
||||
struct
|
||||
{
|
||||
unsigned int length;
|
||||
|
||||
struct
|
||||
{
|
||||
json_char * name;
|
||||
unsigned int name_length;
|
||||
|
||||
struct _json_value * value;
|
||||
|
||||
} * values;
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
decltype(values) begin () const
|
||||
{
|
||||
return values;
|
||||
}
|
||||
decltype(values) end () const
|
||||
{
|
||||
return values + length;
|
||||
}
|
||||
decltype(values) begin () const
|
||||
{
|
||||
return values;
|
||||
}
|
||||
decltype(values) end () const
|
||||
{
|
||||
return values + length;
|
||||
}
|
||||
#endif
|
||||
|
||||
} object;
|
||||
} object;
|
||||
|
||||
struct
|
||||
struct
|
||||
{
|
||||
unsigned int length;
|
||||
struct _json_value ** values;
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
decltype(values) begin () const
|
||||
{
|
||||
return values;
|
||||
}
|
||||
decltype(values) end () const
|
||||
{
|
||||
return values + length;
|
||||
}
|
||||
#endif
|
||||
|
||||
} array;
|
||||
|
||||
} u;
|
||||
|
||||
union
|
||||
{
|
||||
unsigned int length;
|
||||
struct _json_value ** values;
|
||||
struct _json_value * next_alloc;
|
||||
void * object_mem;
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
decltype(values) begin () const
|
||||
{
|
||||
return values;
|
||||
}
|
||||
decltype(values) end () const
|
||||
{
|
||||
return values + length;
|
||||
}
|
||||
#endif
|
||||
|
||||
} array;
|
||||
|
||||
} u;
|
||||
|
||||
union
|
||||
{
|
||||
struct _json_value * next_alloc;
|
||||
void * object_mem;
|
||||
|
||||
} _reserved;
|
||||
} _reserved;
|
||||
|
||||
|
||||
/* Some C++ operator sugar */
|
||||
/* Some C++ operator sugar */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
inline _json_value ()
|
||||
{
|
||||
memset (this, 0, sizeof (_json_value));
|
||||
}
|
||||
|
||||
inline const struct _json_value &operator [] (int index) const
|
||||
{
|
||||
if (type != json_array || index < 0
|
||||
|| ((unsigned int) index) >= u.array.length)
|
||||
inline _json_value ()
|
||||
{
|
||||
memset (this, 0, sizeof (_json_value));
|
||||
}
|
||||
|
||||
inline const struct _json_value &operator [] (int index) const
|
||||
{
|
||||
if (type != json_array || index < 0
|
||||
|| ((unsigned int) index) >= u.array.length)
|
||||
{
|
||||
return json_value_none;
|
||||
}
|
||||
|
||||
return *u.array.values [index];
|
||||
}
|
||||
|
||||
inline const struct _json_value &operator [] (const char * index) const
|
||||
{
|
||||
if (type != json_object)
|
||||
return json_value_none;
|
||||
|
||||
for (unsigned int i = 0; i < u.object.length; ++ i)
|
||||
if (!strcmp (u.object.values [i].name, index))
|
||||
return *u.object.values [i].value;
|
||||
|
||||
return json_value_none;
|
||||
}
|
||||
|
||||
return *u.array.values [index];
|
||||
}
|
||||
|
||||
inline const struct _json_value &operator [] (const char * index) const
|
||||
{
|
||||
if (type != json_object)
|
||||
return json_value_none;
|
||||
|
||||
for (unsigned int i = 0; i < u.object.length; ++ i)
|
||||
if (!strcmp (u.object.values [i].name, index))
|
||||
return *u.object.values [i].value;
|
||||
|
||||
return json_value_none;
|
||||
}
|
||||
|
||||
inline operator const char * () const
|
||||
{
|
||||
switch (type)
|
||||
inline operator const char * () const
|
||||
{
|
||||
case json_string:
|
||||
return u.string.ptr;
|
||||
switch (type)
|
||||
{
|
||||
case json_string:
|
||||
return u.string.ptr;
|
||||
|
||||
default:
|
||||
return "";
|
||||
};
|
||||
}
|
||||
default:
|
||||
return "";
|
||||
};
|
||||
}
|
||||
|
||||
inline operator json_int_t () const
|
||||
{
|
||||
switch (type)
|
||||
inline operator json_int_t () const
|
||||
{
|
||||
case json_integer:
|
||||
return u.integer;
|
||||
switch (type)
|
||||
{
|
||||
case json_integer:
|
||||
return u.integer;
|
||||
|
||||
case json_double:
|
||||
return (json_int_t) u.dbl;
|
||||
case json_double:
|
||||
return (json_int_t) u.dbl;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
inline operator bool () const
|
||||
{
|
||||
if (type != json_boolean)
|
||||
return false;
|
||||
|
||||
return u.boolean != 0;
|
||||
}
|
||||
|
||||
inline operator double () const
|
||||
{
|
||||
switch (type)
|
||||
inline operator bool () const
|
||||
{
|
||||
case json_integer:
|
||||
return (double) u.integer;
|
||||
if (type != json_boolean)
|
||||
return false;
|
||||
|
||||
case json_double:
|
||||
return u.dbl;
|
||||
return u.boolean != 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
inline operator double () const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case json_integer:
|
||||
return (double) u.integer;
|
||||
|
||||
case json_double:
|
||||
return u.dbl;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} json_value;
|
||||
} json_value;
|
||||
|
||||
json_value * json_parse (const json_char * json,
|
||||
size_t length);
|
||||
json_value * json_parse (const json_char * json,
|
||||
size_t length);
|
||||
|
||||
#define json_error_max 128
|
||||
json_value * json_parse_ex (json_settings * settings,
|
||||
const json_char * json,
|
||||
size_t length,
|
||||
char * error);
|
||||
json_value * json_parse_ex (json_settings * settings,
|
||||
const json_char * json,
|
||||
size_t length,
|
||||
char * error);
|
||||
|
||||
void json_value_free (json_value *);
|
||||
void json_value_free (json_value *);
|
||||
|
||||
|
||||
/* Not usually necessary, unless you used a custom mem_alloc and now want to
|
||||
* use a custom mem_free.
|
||||
*/
|
||||
void json_value_free_ex (json_settings * settings,
|
||||
json_value *);
|
||||
/* Not usually necessary, unless you used a custom mem_alloc and now want to
|
||||
* use a custom mem_free.
|
||||
*/
|
||||
void json_value_free_ex (json_settings * settings,
|
||||
json_value *);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+108
-32
@@ -85,6 +85,25 @@ static int nofile = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void server_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void accept_cb (EV_P_ ev_io *w, int revents);
|
||||
static void signal_cb (EV_P_ ev_signal *w, int revents);
|
||||
|
||||
static int create_and_bind (const char *addr, const char *port);
|
||||
static struct remote* connect_to_remote (struct listen_ctx *listener, const char *host, const char *port);
|
||||
static void free_remote (struct remote *remote);
|
||||
static void close_and_free_remote (EV_P_ struct remote *remote);
|
||||
static void free_server (struct server *server);
|
||||
static void close_and_free_server (EV_P_ struct server *server);
|
||||
|
||||
static struct remote* new_remote (int fd, int timeout);
|
||||
static struct server* new_server (int fd, int method);
|
||||
|
||||
static TAILQ_HEAD(connection_head, server) connections;
|
||||
|
||||
#ifndef __MINGW32__
|
||||
int setnonblocking(int fd)
|
||||
{
|
||||
@@ -161,6 +180,17 @@ int create_and_bind(const char *addr, const char *port)
|
||||
return listen_sock;
|
||||
}
|
||||
|
||||
static void free_connections(struct ev_loop *loop)
|
||||
{
|
||||
struct server *iter;
|
||||
while ((iter = TAILQ_FIRST(&connections)) != NULL)
|
||||
{
|
||||
struct remote *remote = iter->remote;
|
||||
close_and_free_server(loop, iter);
|
||||
close_and_free_remote(loop, remote);
|
||||
}
|
||||
}
|
||||
|
||||
static void server_recv_cb (EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
struct server_ctx *server_recv_ctx = (struct server_ctx *)w;
|
||||
@@ -730,7 +760,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents)
|
||||
}
|
||||
}
|
||||
|
||||
struct remote* new_remote(int fd, int timeout)
|
||||
static struct remote* new_remote(int fd, int timeout)
|
||||
{
|
||||
struct remote *remote;
|
||||
remote = malloc(sizeof(struct remote));
|
||||
@@ -787,7 +817,7 @@ static void close_and_free_remote(EV_P_ struct remote *remote)
|
||||
}
|
||||
}
|
||||
|
||||
struct server* new_server(int fd, int method)
|
||||
static struct server* new_server(int fd, int method)
|
||||
{
|
||||
struct server *server;
|
||||
server = malloc(sizeof(struct server));
|
||||
@@ -816,35 +846,37 @@ struct server* new_server(int fd, int method)
|
||||
server->e_ctx = NULL;
|
||||
server->d_ctx = NULL;
|
||||
}
|
||||
|
||||
TAILQ_INSERT_HEAD(&connections, server, entries);
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
static void free_server(struct server *server)
|
||||
{
|
||||
if (server != NULL)
|
||||
TAILQ_REMOVE(&connections, server, entries);
|
||||
|
||||
if (server->remote != NULL)
|
||||
{
|
||||
if (server->remote != NULL)
|
||||
{
|
||||
server->remote->server = NULL;
|
||||
}
|
||||
if (server->e_ctx != NULL)
|
||||
{
|
||||
cipher_context_release(&server->e_ctx->evp);
|
||||
free(server->e_ctx);
|
||||
}
|
||||
if (server->d_ctx != NULL)
|
||||
{
|
||||
cipher_context_release(&server->d_ctx->evp);
|
||||
free(server->d_ctx);
|
||||
}
|
||||
if (server->buf != NULL)
|
||||
{
|
||||
free(server->buf);
|
||||
}
|
||||
free(server->recv_ctx);
|
||||
free(server->send_ctx);
|
||||
free(server);
|
||||
server->remote->server = NULL;
|
||||
}
|
||||
if (server->e_ctx != NULL)
|
||||
{
|
||||
cipher_context_release(&server->e_ctx->evp);
|
||||
free(server->e_ctx);
|
||||
}
|
||||
if (server->d_ctx != NULL)
|
||||
{
|
||||
cipher_context_release(&server->d_ctx->evp);
|
||||
free(server->d_ctx);
|
||||
}
|
||||
if (server->buf != NULL)
|
||||
{
|
||||
free(server->buf);
|
||||
}
|
||||
free(server->recv_ctx);
|
||||
free(server->send_ctx);
|
||||
free(server);
|
||||
}
|
||||
|
||||
static void close_and_free_server(EV_P_ struct server *server)
|
||||
@@ -917,6 +949,18 @@ static struct remote* connect_to_remote(struct listen_ctx *listener,
|
||||
return remote;
|
||||
}
|
||||
|
||||
static void signal_cb (EV_P_ ev_signal *w, int revents)
|
||||
{
|
||||
if (revents & EV_SIGNAL)
|
||||
{
|
||||
switch (w->signum)
|
||||
{
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
ev_unloop(EV_A_ EVUNLOOP_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void accept_cb (EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
@@ -1097,11 +1141,18 @@ int main (int argc, char **argv)
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_init();
|
||||
#else
|
||||
#endif
|
||||
|
||||
// ignore SIGPIPE
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGABRT, SIG_IGN);
|
||||
#endif
|
||||
|
||||
struct ev_signal sigint_watcher;
|
||||
struct ev_signal sigterm_watcher;
|
||||
ev_signal_init(&sigint_watcher, signal_cb, SIGINT);
|
||||
ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM);
|
||||
ev_signal_start(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_start(EV_DEFAULT, &sigterm_watcher);
|
||||
|
||||
// Setup keys
|
||||
LOGD("initialize ciphers... %s", method);
|
||||
@@ -1136,7 +1187,7 @@ int main (int argc, char **argv)
|
||||
listen_ctx.iface = iface;
|
||||
listen_ctx.method = m;
|
||||
|
||||
struct ev_loop *loop = ev_default_loop(0);
|
||||
struct ev_loop *loop = EV_DEFAULT;
|
||||
if (!loop)
|
||||
{
|
||||
FATAL("ev_loop error.");
|
||||
@@ -1148,15 +1199,24 @@ int main (int argc, char **argv)
|
||||
if (udprelay)
|
||||
{
|
||||
LOGD("udprelay enabled.");
|
||||
udprelay_init(local_addr, local_port, remote_addr[0].host, remote_addr[0].port, m, listen_ctx.timeout, iface);
|
||||
init_udprelay(local_addr, local_port, remote_addr[0].host, remote_addr[0].port, m, listen_ctx.timeout, iface);
|
||||
}
|
||||
|
||||
// setuid
|
||||
if (user != NULL)
|
||||
run_as(user);
|
||||
|
||||
// Init connections
|
||||
TAILQ_INIT(&connections);
|
||||
|
||||
ev_run (loop, 0);
|
||||
|
||||
free_connections(loop);
|
||||
free_udprelay();
|
||||
|
||||
ev_io_stop(loop, &listen_ctx.io);
|
||||
free(listen_ctx.remote_addr);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_cleanup();
|
||||
#endif
|
||||
@@ -1198,11 +1258,18 @@ int start_ss_local_server(profile_t profile)
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_init();
|
||||
#else
|
||||
#endif
|
||||
|
||||
// ignore SIGPIPE
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGABRT, SIG_IGN);
|
||||
#endif
|
||||
|
||||
struct ev_signal sigint_watcher;
|
||||
struct ev_signal sigterm_watcher;
|
||||
ev_signal_init(&sigint_watcher, signal_cb, SIGINT);
|
||||
ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM);
|
||||
ev_signal_start(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_start(EV_DEFAULT, &sigterm_watcher);
|
||||
|
||||
// Setup keys
|
||||
LOGD("initialize ciphers... %s", method);
|
||||
@@ -1234,7 +1301,7 @@ int start_ss_local_server(profile_t profile)
|
||||
listen_ctx.method = m;
|
||||
listen_ctx.iface = NULL;
|
||||
|
||||
struct ev_loop *loop = ev_default_loop(0);
|
||||
struct ev_loop *loop = EV_DEFAULT;
|
||||
if (!loop)
|
||||
{
|
||||
FATAL("ev_loop error.");
|
||||
@@ -1246,11 +1313,20 @@ int start_ss_local_server(profile_t profile)
|
||||
if (udprelay)
|
||||
{
|
||||
LOGD("udprelay enabled.");
|
||||
udprelay_init(local_addr, local_port_str, remote_host, remote_port_str, m, listen_ctx.timeout, NULL);
|
||||
init_udprelay(local_addr, local_port_str, remote_host, remote_port_str, m, listen_ctx.timeout, NULL);
|
||||
}
|
||||
|
||||
// Init connections
|
||||
TAILQ_INIT(&connections);
|
||||
|
||||
ev_run (loop, 0);
|
||||
|
||||
free_connections(loop);
|
||||
free_udprelay();
|
||||
|
||||
ev_io_stop(loop, &listen_ctx.io);
|
||||
free(listen_ctx.remote_addr);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_cleanup();
|
||||
#endif
|
||||
|
||||
+4
-18
@@ -23,11 +23,12 @@
|
||||
#ifndef _LOCAL_H
|
||||
#define _LOCAL_H
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <ev.h>
|
||||
#include "encrypt.h"
|
||||
#include "jconf.h"
|
||||
|
||||
#include "include.h"
|
||||
#include "common.h"
|
||||
|
||||
struct listen_ctx
|
||||
{
|
||||
@@ -61,6 +62,8 @@ struct server
|
||||
struct server_ctx *send_ctx;
|
||||
struct listen_ctx *listener;
|
||||
struct remote *remote;
|
||||
|
||||
TAILQ_ENTRY(server) entries;
|
||||
};
|
||||
|
||||
struct remote_ctx
|
||||
@@ -84,21 +87,4 @@ struct remote
|
||||
struct addrinfo *addr_info;
|
||||
};
|
||||
|
||||
// exported for library use
|
||||
int create_and_bind(const char *addr, const char *port);
|
||||
void accept_cb (EV_P_ ev_io *w, int revents);
|
||||
|
||||
static struct remote* connect_to_remote(struct listen_ctx *listener, const char *host, const char *port);
|
||||
static void server_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void free_remote(struct remote *remote);
|
||||
static void close_and_free_remote(EV_P_ struct remote *remote);
|
||||
static void free_server(struct server *server);
|
||||
static void close_and_free_server(EV_P_ struct server *server);
|
||||
|
||||
struct remote* new_remote(int fd, int timeout);
|
||||
struct server* new_server(int fd, int method);
|
||||
|
||||
#endif // _LOCAL_H
|
||||
|
||||
+21
-6
@@ -64,6 +64,21 @@
|
||||
#define IP6T_SO_ORIGINAL_DST 80
|
||||
#endif
|
||||
|
||||
static void accept_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_send_cb (EV_P_ ev_io *w, int revents);
|
||||
|
||||
static struct remote* new_remote(int fd, int timeout);
|
||||
static struct server* new_server(int fd, int method);
|
||||
|
||||
static void free_remote(struct remote *remote);
|
||||
static void close_and_free_remote(EV_P_ struct remote *remote);
|
||||
static void free_server(struct server *server);
|
||||
static void close_and_free_server(EV_P_ struct server *server);
|
||||
|
||||
|
||||
int getdestaddr(int fd, struct sockaddr_storage *destaddr)
|
||||
{
|
||||
socklen_t socklen = sizeof(*destaddr);
|
||||
@@ -510,7 +525,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents)
|
||||
}
|
||||
}
|
||||
|
||||
struct remote* new_remote(int fd, int timeout)
|
||||
static struct remote* new_remote(int fd, int timeout)
|
||||
{
|
||||
struct remote *remote;
|
||||
remote = malloc(sizeof(struct remote));
|
||||
@@ -530,7 +545,7 @@ struct remote* new_remote(int fd, int timeout)
|
||||
return remote;
|
||||
}
|
||||
|
||||
void free_remote(struct remote *remote)
|
||||
static void free_remote(struct remote *remote)
|
||||
{
|
||||
if (remote != NULL)
|
||||
{
|
||||
@@ -548,7 +563,7 @@ void free_remote(struct remote *remote)
|
||||
}
|
||||
}
|
||||
|
||||
void close_and_free_remote(EV_P_ struct remote *remote)
|
||||
static void close_and_free_remote(EV_P_ struct remote *remote)
|
||||
{
|
||||
if (remote != NULL)
|
||||
{
|
||||
@@ -560,7 +575,7 @@ void close_and_free_remote(EV_P_ struct remote *remote)
|
||||
}
|
||||
}
|
||||
|
||||
struct server* new_server(int fd, int method)
|
||||
static struct server* new_server(int fd, int method)
|
||||
{
|
||||
struct server *server;
|
||||
server = malloc(sizeof(struct server));
|
||||
@@ -591,7 +606,7 @@ struct server* new_server(int fd, int method)
|
||||
return server;
|
||||
}
|
||||
|
||||
void free_server(struct server *server)
|
||||
static void free_server(struct server *server)
|
||||
{
|
||||
if (server != NULL)
|
||||
{
|
||||
@@ -619,7 +634,7 @@ void free_server(struct server *server)
|
||||
}
|
||||
}
|
||||
|
||||
void close_and_free_server(EV_P_ struct server *server)
|
||||
static void close_and_free_server(EV_P_ struct server *server)
|
||||
{
|
||||
if (server != NULL)
|
||||
{
|
||||
|
||||
-13
@@ -78,17 +78,4 @@ struct remote
|
||||
struct server *server;
|
||||
};
|
||||
|
||||
|
||||
static void accept_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_send_cb (EV_P_ ev_io *w, int revents);
|
||||
struct remote* new_remote(int fd, int timeout);
|
||||
void free_remote(struct remote *remote);
|
||||
void close_and_free_remote(EV_P_ struct remote *remote);
|
||||
struct server* new_server(int fd, int method);
|
||||
void free_server(struct server *server);
|
||||
void close_and_free_server(EV_P_ struct server *server);
|
||||
|
||||
#endif // _LOCAL_H
|
||||
|
||||
+42
-16
@@ -62,6 +62,24 @@
|
||||
#define BUF_SIZE 2048
|
||||
#endif
|
||||
|
||||
static void accept_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_resolve_cb(EV_P_ ev_io *w, int revents);
|
||||
static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents);
|
||||
|
||||
static struct remote* new_remote(int fd);
|
||||
static struct server* new_server(int fd, struct listen_ctx *listener);
|
||||
static struct remote *connect_to_remote(struct addrinfo *res, struct server *server);
|
||||
|
||||
static void free_remote(struct remote *remote);
|
||||
static void close_and_free_remote(EV_P_ struct remote *remote);
|
||||
static void free_server(struct server *server);
|
||||
static void close_and_free_server(EV_P_ struct server *server);
|
||||
|
||||
|
||||
int verbose = 0;
|
||||
int udprelay = 0;
|
||||
#ifdef TCP_FASTOPEN
|
||||
@@ -165,7 +183,7 @@ int create_and_bind(const char *host, const char *port)
|
||||
return listen_sock;
|
||||
}
|
||||
|
||||
struct remote *connect_to_remote(struct addrinfo *res, struct server *server)
|
||||
static struct remote *connect_to_remote(struct addrinfo *res, struct server *server)
|
||||
{
|
||||
int sockfd;
|
||||
int opt = 1;
|
||||
@@ -196,30 +214,38 @@ struct remote *connect_to_remote(struct addrinfo *res, struct server *server)
|
||||
#endif
|
||||
|
||||
#ifdef TCP_FASTOPEN
|
||||
if (fast_open) {
|
||||
if (fast_open)
|
||||
{
|
||||
ssize_t s = sendto(sockfd, server->buf + server->buf_idx, server->buf_len, MSG_FASTOPEN, res->ai_addr, res->ai_addrlen);
|
||||
if (s == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
if (s == -1)
|
||||
{
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
{
|
||||
// The remote server doesn't support tfo or it's the first connection to the server.
|
||||
// It will automatically fall back to conventional TCP.
|
||||
}
|
||||
else if (errno == EOPNOTSUPP || errno == EPROTONOSUPPORT || errno == ENOPROTOOPT) {
|
||||
else if (errno == EOPNOTSUPP || errno == EPROTONOSUPPORT || errno == ENOPROTOOPT)
|
||||
{
|
||||
LOGE("fast open is not supported on this platform");
|
||||
connect(sockfd, res->ai_addr, res->ai_addrlen);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
ERROR("sendto");
|
||||
}
|
||||
}
|
||||
else if (s < server->buf_len) {
|
||||
else if (s < server->buf_len)
|
||||
{
|
||||
server->buf_idx += s;
|
||||
server->buf_len -= s;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
server->buf_idx = 0;
|
||||
server->buf_len = 0;
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
#endif
|
||||
connect(sockfd, res->ai_addr, res->ai_addrlen);
|
||||
|
||||
@@ -799,7 +825,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents)
|
||||
}
|
||||
}
|
||||
|
||||
struct remote* new_remote(int fd)
|
||||
static struct remote* new_remote(int fd)
|
||||
{
|
||||
if (verbose) remote_conn++;
|
||||
|
||||
@@ -821,7 +847,7 @@ struct remote* new_remote(int fd)
|
||||
return remote;
|
||||
}
|
||||
|
||||
void free_remote(struct remote *remote)
|
||||
static void free_remote(struct remote *remote)
|
||||
{
|
||||
if (remote != NULL)
|
||||
{
|
||||
@@ -839,7 +865,7 @@ void free_remote(struct remote *remote)
|
||||
}
|
||||
}
|
||||
|
||||
void close_and_free_remote(EV_P_ struct remote *remote)
|
||||
static void close_and_free_remote(EV_P_ struct remote *remote)
|
||||
{
|
||||
if (remote != NULL)
|
||||
{
|
||||
@@ -855,7 +881,7 @@ void close_and_free_remote(EV_P_ struct remote *remote)
|
||||
}
|
||||
}
|
||||
|
||||
struct server* new_server(int fd, struct listen_ctx *listener)
|
||||
static struct server* new_server(int fd, struct listen_ctx *listener)
|
||||
{
|
||||
if (verbose) server_conn++;
|
||||
|
||||
@@ -893,7 +919,7 @@ struct server* new_server(int fd, struct listen_ctx *listener)
|
||||
return server;
|
||||
}
|
||||
|
||||
void free_server(struct server *server)
|
||||
static void free_server(struct server *server)
|
||||
{
|
||||
if (server != NULL)
|
||||
{
|
||||
@@ -921,7 +947,7 @@ void free_server(struct server *server)
|
||||
}
|
||||
}
|
||||
|
||||
void close_and_free_server(EV_P_ struct server *server)
|
||||
static void close_and_free_server(EV_P_ struct server *server)
|
||||
{
|
||||
if (server != NULL)
|
||||
{
|
||||
@@ -1180,7 +1206,7 @@ int main (int argc, char **argv)
|
||||
if (udprelay)
|
||||
{
|
||||
LOGD("udprelay enabled.");
|
||||
udprelay_init(server_host[0], server_port, dns_thread_num, m, listen_ctx->timeout, iface);
|
||||
init_udprelay(server_host[0], server_port, dns_thread_num, m, listen_ctx->timeout, iface);
|
||||
}
|
||||
|
||||
// setuid
|
||||
|
||||
+1
-18
@@ -30,7 +30,7 @@
|
||||
#include "jconf.h"
|
||||
#include "asyncns.h"
|
||||
|
||||
#include "include.h"
|
||||
#include "common.h"
|
||||
|
||||
struct listen_ctx
|
||||
{
|
||||
@@ -85,21 +85,4 @@ struct remote
|
||||
struct server *server;
|
||||
};
|
||||
|
||||
|
||||
static void accept_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_resolve_cb(EV_P_ ev_io *w, int revents);
|
||||
static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents);
|
||||
|
||||
struct remote* new_remote(int fd);
|
||||
struct remote *connect_to_remote(struct addrinfo *res, struct server *server);
|
||||
void free_remote(struct remote *remote);
|
||||
void close_and_free_remote(EV_P_ struct remote *remote);
|
||||
struct server* new_server(int fd, struct listen_ctx *listener);
|
||||
void free_server(struct server *server);
|
||||
void close_and_free_server(EV_P_ struct server *server);
|
||||
|
||||
#endif // _SERVER_H
|
||||
|
||||
+16
-15
@@ -22,10 +22,11 @@
|
||||
#ifndef _SHADOWSOCKS_H
|
||||
#define _SHADOWSOCKS_H
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
/* Required */
|
||||
char *remote_host; // hostname or ip of remote server
|
||||
char *local_addr; // local ip to bind
|
||||
char *local_addr; // local ip to bind
|
||||
char *method; // encryption method
|
||||
char *password; // password of remote server
|
||||
int remote_port; // port number of remote server
|
||||
@@ -59,21 +60,21 @@ const profile_t EXAMPLE_PROFILE = {
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create and start a shadowsocks local server.
|
||||
*
|
||||
* Calling this function will block the current thread forever if the server
|
||||
* starts successfully.
|
||||
*
|
||||
* Make sure start the server in a seperate process to avoid any potential
|
||||
* memory and socket leak.
|
||||
*
|
||||
* If failed, -1 is returned. Errors will output to the log file.
|
||||
*/
|
||||
int start_ss_local_server(profile_t profile);
|
||||
/*
|
||||
* Create and start a shadowsocks local server.
|
||||
*
|
||||
* Calling this function will block the current thread forever if the server
|
||||
* starts successfully.
|
||||
*
|
||||
* Make sure start the server in a seperate process to avoid any potential
|
||||
* memory and socket leak.
|
||||
*
|
||||
* If failed, -1 is returned. Errors will output to the log file.
|
||||
*/
|
||||
int start_ss_local_server(profile_t profile);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+17
-3
@@ -67,6 +67,20 @@
|
||||
#define BUF_SIZE 2048
|
||||
#endif
|
||||
|
||||
static void accept_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_send_cb (EV_P_ ev_io *w, int revents);
|
||||
|
||||
static struct remote* new_remote(int fd, int timeout);
|
||||
static struct server* new_server(int fd, int method);
|
||||
|
||||
static void free_remote(struct remote *remote);
|
||||
static void close_and_free_remote(EV_P_ struct remote *remote);
|
||||
static void free_server(struct server *server);
|
||||
static void close_and_free_server(EV_P_ struct server *server);
|
||||
|
||||
int verbose = 0;
|
||||
int udprelay = 0;
|
||||
|
||||
@@ -508,7 +522,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents)
|
||||
}
|
||||
}
|
||||
|
||||
struct remote* new_remote(int fd, int timeout)
|
||||
static struct remote* new_remote(int fd, int timeout)
|
||||
{
|
||||
struct remote *remote;
|
||||
remote = malloc(sizeof(struct remote));
|
||||
@@ -558,7 +572,7 @@ static void close_and_free_remote(EV_P_ struct remote *remote)
|
||||
}
|
||||
}
|
||||
|
||||
struct server* new_server(int fd, int method)
|
||||
static struct server* new_server(int fd, int method)
|
||||
{
|
||||
struct server *server;
|
||||
server = malloc(sizeof(struct server));
|
||||
@@ -866,7 +880,7 @@ int main (int argc, char **argv)
|
||||
if (udprelay)
|
||||
{
|
||||
LOGD("udprelay enabled.");
|
||||
udprelay_init(local_addr, local_port, remote_addr[0].host, remote_addr[0].port,
|
||||
init_udprelay(local_addr, local_port, remote_addr[0].host, remote_addr[0].port,
|
||||
tunnel_addr, m, listen_ctx.timeout, iface);
|
||||
}
|
||||
|
||||
|
||||
+1
-14
@@ -27,7 +27,7 @@
|
||||
#include "encrypt.h"
|
||||
#include "jconf.h"
|
||||
|
||||
#include "include.h"
|
||||
#include "common.h"
|
||||
|
||||
struct listen_ctx
|
||||
{
|
||||
@@ -82,17 +82,4 @@ struct remote
|
||||
struct server *server;
|
||||
};
|
||||
|
||||
static void accept_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void server_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_recv_cb (EV_P_ ev_io *w, int revents);
|
||||
static void remote_send_cb (EV_P_ ev_io *w, int revents);
|
||||
static void free_remote(struct remote *remote);
|
||||
static void close_and_free_remote(EV_P_ struct remote *remote);
|
||||
static void free_server(struct server *server);
|
||||
static void close_and_free_server(EV_P_ struct server *server);
|
||||
|
||||
struct remote* new_remote(int fd, int timeout);
|
||||
struct server* new_server(int fd, int method);
|
||||
|
||||
#endif // _TUNNEL_H
|
||||
|
||||
+27
-4
@@ -81,6 +81,9 @@
|
||||
|
||||
extern int verbose;
|
||||
|
||||
static struct server_ctx *server_ctx = NULL;
|
||||
struct resolve_ctx *resolve_ctx = NULL;
|
||||
|
||||
#ifndef __MINGW32__
|
||||
static int setnonblocking(int fd)
|
||||
{
|
||||
@@ -895,7 +898,7 @@ void free_cb(void *element)
|
||||
close_and_free_remote(EV_DEFAULT, remote_ctx);
|
||||
}
|
||||
|
||||
int udprelay_init(const char *server_host, const char *server_port,
|
||||
int init_udprelay(const char *server_host, const char *server_port,
|
||||
#ifdef UDPRELAY_LOCAL
|
||||
const char *remote_host, const char *remote_port,
|
||||
#ifdef UDPRELAY_TUNNEL
|
||||
@@ -907,7 +910,6 @@ int udprelay_init(const char *server_host, const char *server_port,
|
||||
#endif
|
||||
int method, int timeout, const char *iface)
|
||||
{
|
||||
|
||||
// Inilitialize ev loop
|
||||
struct ev_loop *loop = EV_DEFAULT;
|
||||
|
||||
@@ -925,7 +927,7 @@ int udprelay_init(const char *server_host, const char *server_port,
|
||||
{
|
||||
FATAL("asyncns failed");
|
||||
}
|
||||
struct resolve_ctx *resolve_ctx = malloc(sizeof(struct resolve_ctx));
|
||||
resolve_ctx = malloc(sizeof(struct resolve_ctx));
|
||||
resolve_ctx->asyncns = asyncns;
|
||||
|
||||
int asyncnsfd = asyncns_fd(asyncns);
|
||||
@@ -941,7 +943,7 @@ int udprelay_init(const char *server_host, const char *server_port,
|
||||
}
|
||||
setnonblocking(serverfd);
|
||||
|
||||
struct server_ctx *server_ctx = new_server_ctx(serverfd);
|
||||
server_ctx = new_server_ctx(serverfd);
|
||||
server_ctx->timeout = timeout;
|
||||
server_ctx->method = method;
|
||||
server_ctx->iface = iface;
|
||||
@@ -962,3 +964,24 @@ int udprelay_init(const char *server_host, const char *server_port,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_udprelay()
|
||||
{
|
||||
struct ev_loop *loop = EV_DEFAULT;
|
||||
#ifdef UDPRELAY_REMOTE
|
||||
if (resolve_ctx != NULL)
|
||||
{
|
||||
asyncns_free(resolve_ctx->asyncns);
|
||||
ev_io_stop(loop, &resolve_ctx->io);
|
||||
free(resolve_ctx);
|
||||
resolve_ctx = NULL;
|
||||
}
|
||||
#endif
|
||||
if (server_ctx != NULL)
|
||||
{
|
||||
ev_io_stop(loop, &server_ctx->io);
|
||||
close(server_ctx->fd);
|
||||
cache_delete(server_ctx->conn_cache, 0);
|
||||
free(server_ctx);
|
||||
server_ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -35,7 +35,7 @@
|
||||
|
||||
#include "cache.h"
|
||||
|
||||
#include "include.h"
|
||||
#include "common.h"
|
||||
|
||||
#define MAX_UDP_PACKET_SIZE (64 * 1024)
|
||||
|
||||
@@ -47,7 +47,6 @@ struct server_ctx
|
||||
int timeout;
|
||||
const char *iface;
|
||||
struct cache *conn_cache;
|
||||
char *buf; // server send from, remote recv into
|
||||
#ifdef UDPRELAY_REMOTE
|
||||
asyncns_t *asyncns;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user