mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-28 11:43:50 +00:00
refine server end
This commit is contained in:
+21
-14
@@ -698,20 +698,18 @@ static struct remote * new_remote(int fd, int timeout)
|
||||
|
||||
static void free_remote(struct remote *remote)
|
||||
{
|
||||
if (remote != NULL) {
|
||||
if (remote->server != NULL) {
|
||||
remote->server->remote = NULL;
|
||||
}
|
||||
if (remote->buf != NULL) {
|
||||
free(remote->buf);
|
||||
}
|
||||
if (remote->addr_info != NULL) {
|
||||
freeaddrinfo(remote->addr_info);
|
||||
}
|
||||
free(remote->recv_ctx);
|
||||
free(remote->send_ctx);
|
||||
free(remote);
|
||||
if (remote->server != NULL) {
|
||||
remote->server->remote = NULL;
|
||||
}
|
||||
if (remote->buf != NULL) {
|
||||
free(remote->buf);
|
||||
}
|
||||
if (remote->addr_info != NULL) {
|
||||
freeaddrinfo(remote->addr_info);
|
||||
}
|
||||
free(remote->recv_ctx);
|
||||
free(remote->send_ctx);
|
||||
free(remote);
|
||||
}
|
||||
|
||||
static void close_and_free_remote(EV_P_ struct remote *remote)
|
||||
@@ -1133,6 +1131,9 @@ int main(int argc, char **argv)
|
||||
winsock_cleanup();
|
||||
#endif
|
||||
|
||||
ev_signal_stop(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_stop(EV_DEFAULT, &sigterm_watcher);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
@@ -1238,15 +1239,21 @@ int start_ss_local_server(profile_t profile)
|
||||
|
||||
// Clean up
|
||||
free_connections(loop);
|
||||
free_udprelay();
|
||||
if (udprelay) {
|
||||
free_udprelay();
|
||||
}
|
||||
|
||||
ev_io_stop(loop, &listen_ctx.io);
|
||||
free(listen_ctx.remote_addr);
|
||||
close(listen_ctx.fd);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_cleanup();
|
||||
#endif
|
||||
|
||||
ev_signal_stop(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_stop(EV_DEFAULT, &sigterm_watcher);
|
||||
|
||||
// cannot reach here
|
||||
return 0;
|
||||
}
|
||||
|
||||
+93
-29
@@ -37,6 +37,8 @@
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <libcork/core.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
@@ -62,6 +64,7 @@
|
||||
#define BUF_SIZE 2048
|
||||
#endif
|
||||
|
||||
static void signal_cb(EV_P_ ev_signal *w, int revents);
|
||||
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);
|
||||
@@ -80,7 +83,6 @@ 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
|
||||
@@ -92,6 +94,20 @@ static int nofile = 0;
|
||||
static int remote_conn = 0;
|
||||
static int server_conn = 0;
|
||||
|
||||
static struct cork_dllist connections;
|
||||
|
||||
static void free_connections(struct ev_loop *loop)
|
||||
{
|
||||
struct cork_dllist_item *curr;
|
||||
for (curr = cork_dllist_start(&connections); !cork_dllist_is_end(&connections, curr);
|
||||
curr = curr->next) {
|
||||
struct server *server = cork_container_of(curr, struct server, entries);
|
||||
struct remote *remote = server->remote;
|
||||
close_and_free_server(loop, server);
|
||||
close_and_free_remote(loop, remote);
|
||||
}
|
||||
}
|
||||
|
||||
int setnonblocking(int fd)
|
||||
{
|
||||
int flags;
|
||||
@@ -743,17 +759,15 @@ static struct remote * new_remote(int fd)
|
||||
|
||||
static void free_remote(struct remote *remote)
|
||||
{
|
||||
if (remote != NULL) {
|
||||
if (remote->server != NULL) {
|
||||
remote->server->remote = NULL;
|
||||
}
|
||||
if (remote->buf != NULL) {
|
||||
free(remote->buf);
|
||||
}
|
||||
free(remote->recv_ctx);
|
||||
free(remote->send_ctx);
|
||||
free(remote);
|
||||
if (remote->server != NULL) {
|
||||
remote->server->remote = NULL;
|
||||
}
|
||||
if (remote->buf != NULL) {
|
||||
free(remote->buf);
|
||||
}
|
||||
free(remote->recv_ctx);
|
||||
free(remote->send_ctx);
|
||||
free(remote);
|
||||
}
|
||||
|
||||
static void close_and_free_remote(EV_P_ struct remote *remote)
|
||||
@@ -805,30 +819,33 @@ static struct server * new_server(int fd, struct listen_ctx *listener)
|
||||
server->buf_len = 0;
|
||||
server->buf_idx = 0;
|
||||
server->remote = NULL;
|
||||
|
||||
cork_dllist_add(&connections, &server->entries);
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
static void free_server(struct server *server)
|
||||
{
|
||||
if (server != 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);
|
||||
cork_dllist_remove(&server->entries);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void close_and_free_server(EV_P_ struct server *server)
|
||||
@@ -850,6 +867,17 @@ static void close_and_free_server(EV_P_ struct server *server)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void accept_cb(EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
struct listen_ctx *listener = (struct listen_ctx *)w;
|
||||
@@ -1025,6 +1053,13 @@ int main(int argc, char **argv)
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
signal(SIGABRT, SIG_IGN);
|
||||
|
||||
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 asyncns
|
||||
asyncns_t *asyncns;
|
||||
if (!(asyncns = asyncns_new(dns_thread_num))) {
|
||||
@@ -1094,8 +1129,37 @@ int main(int argc, char **argv)
|
||||
run_as(user);
|
||||
}
|
||||
|
||||
// Init connections
|
||||
cork_dllist_init(&connections);
|
||||
|
||||
// start ev loop
|
||||
ev_run(loop, 0);
|
||||
|
||||
if (verbose) {
|
||||
LOGD("closed nicely.");
|
||||
}
|
||||
|
||||
// Clean up
|
||||
listen_ctx = &listen_ctx_list[0];
|
||||
ev_io_stop(loop, &listen_ctx->io);
|
||||
asyncns_free(listen_ctx->asyncns);
|
||||
close(listen_ctx->fd);
|
||||
|
||||
for (int i = 1; i <= server_num; i++) {
|
||||
listen_ctx = &listen_ctx_list[i];
|
||||
ev_io_stop(loop, &listen_ctx->io);
|
||||
close(listen_ctx->fd);
|
||||
}
|
||||
|
||||
free_connections(loop);
|
||||
|
||||
if (udprelay) {
|
||||
free_udprelay();
|
||||
}
|
||||
|
||||
ev_signal_stop(EV_DEFAULT, &sigint_watcher);
|
||||
ev_signal_stop(EV_DEFAULT, &sigterm_watcher);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <ev.h>
|
||||
#include <time.h>
|
||||
#include <libcork/ds.h>
|
||||
|
||||
#include "encrypt.h"
|
||||
#include "jconf.h"
|
||||
@@ -62,6 +63,8 @@ struct server {
|
||||
struct server_ctx *send_ctx;
|
||||
struct listen_ctx *listen_ctx;
|
||||
struct remote *remote;
|
||||
|
||||
struct cork_dllist_item entries;
|
||||
};
|
||||
|
||||
struct remote_ctx {
|
||||
|
||||
+6
-2
@@ -880,11 +880,13 @@ int init_udprelay(const char *server_host, const char *server_port,
|
||||
FATAL("asyncns failed");
|
||||
}
|
||||
resolve_ctx = malloc(sizeof(struct resolve_ctx));
|
||||
resolve_ctx->asyncns = asyncns;
|
||||
|
||||
int asyncnsfd = asyncns_fd(asyncns);
|
||||
ev_io_init(&resolve_ctx->io, query_resolve_cb, asyncnsfd, EV_READ);
|
||||
ev_io_start(loop, &resolve_ctx->io);
|
||||
|
||||
resolve_ctx->asyncns = asyncns;
|
||||
resolve_ctx->asyncnsfd = asyncnsfd;
|
||||
#endif
|
||||
|
||||
// Bind to port
|
||||
@@ -920,8 +922,10 @@ 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);
|
||||
asyncns_free(resolve_ctx->asyncns);
|
||||
|
||||
close(resolve_ctx->asyncnsfd);
|
||||
free(resolve_ctx);
|
||||
resolve_ctx = NULL;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ struct server_ctx {
|
||||
struct resolve_ctx {
|
||||
ev_io io;
|
||||
asyncns_t *asyncns;
|
||||
int asyncnsfd;
|
||||
};
|
||||
|
||||
struct query_ctx {
|
||||
|
||||
Reference in New Issue
Block a user