|
@ -83,6 +83,15 @@ setnonblocking(int fd) |
|
|
return fcntl(fd, F_SETFL, flags | O_NONBLOCK); |
|
|
return fcntl(fd, F_SETFL, flags | O_NONBLOCK); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
|
destroy_server(struct server *server) { |
|
|
|
|
|
// function used to free memories alloced in **get_server** |
|
|
|
|
|
if (server->method) ss_free(server->method); |
|
|
|
|
|
if (server->plugin) ss_free(server->plugin); |
|
|
|
|
|
if (server->plugin_opts) ss_free(server->plugin_opts); |
|
|
|
|
|
if (server->mode) ss_free(server->mode); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static void |
|
|
static void |
|
|
build_config(char *prefix, struct server *server) |
|
|
build_config(char *prefix, struct server *server) |
|
|
{ |
|
|
{ |
|
@ -102,6 +111,11 @@ build_config(char *prefix, struct server *server) |
|
|
fprintf(f, "{\n"); |
|
|
fprintf(f, "{\n"); |
|
|
fprintf(f, "\"server_port\":\"%s\",\n", server->port); |
|
|
fprintf(f, "\"server_port\":\"%s\",\n", server->port); |
|
|
fprintf(f, "\"password\":\"%s\",\n", server->password); |
|
|
fprintf(f, "\"password\":\"%s\",\n", server->password); |
|
|
|
|
|
if (server->fast_open[0]) fprintf(f, "\"fast_open\": %s,\n", server->fast_open); |
|
|
|
|
|
if (server->mode) fprintf(f, "\"mode\":\"%s\",\n", server->mode); |
|
|
|
|
|
if (server->method) fprintf(f, "\"method\":\"%s\",\n", server->method); |
|
|
|
|
|
if (server->plugin) fprintf(f, "\"plugin\":\"%s\",\n", server->plugin); |
|
|
|
|
|
if (server->plugin_opts) fprintf(f, "\"plugin_opts\":\"%s\",\n", server->plugin_opts); |
|
|
fprintf(f, "}\n"); |
|
|
fprintf(f, "}\n"); |
|
|
fclose(f); |
|
|
fclose(f); |
|
|
ss_free(path); |
|
|
ss_free(path); |
|
@ -111,14 +125,16 @@ static char * |
|
|
construct_command_line(struct manager_ctx *manager, struct server *server) |
|
|
construct_command_line(struct manager_ctx *manager, struct server *server) |
|
|
{ |
|
|
{ |
|
|
static char cmd[BUF_SIZE]; |
|
|
static char cmd[BUF_SIZE]; |
|
|
|
|
|
char *method = manager->method; |
|
|
int i; |
|
|
int i; |
|
|
|
|
|
|
|
|
build_config(working_dir, server); |
|
|
build_config(working_dir, server); |
|
|
|
|
|
|
|
|
|
|
|
if (server->method) method = server->method; |
|
|
memset(cmd, 0, BUF_SIZE); |
|
|
memset(cmd, 0, BUF_SIZE); |
|
|
snprintf(cmd, BUF_SIZE, |
|
|
snprintf(cmd, BUF_SIZE, |
|
|
"%s -m %s --manager-address %s -f %s/.shadowsocks_%s.pid -c %s/.shadowsocks_%s.conf", |
|
|
"%s -m %s --manager-address %s -f %s/.shadowsocks_%s.pid -c %s/.shadowsocks_%s.conf", |
|
|
executable, manager->method, manager->manager_address, |
|
|
|
|
|
|
|
|
executable, method, manager->manager_address, |
|
|
working_dir, server->port, working_dir, server->port); |
|
|
working_dir, server->port, working_dir, server->port); |
|
|
|
|
|
|
|
|
if (manager->acl != NULL) { |
|
|
if (manager->acl != NULL) { |
|
@ -143,15 +159,15 @@ construct_command_line(struct manager_ctx *manager, struct server *server) |
|
|
int len = strlen(cmd); |
|
|
int len = strlen(cmd); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " -v"); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " -v"); |
|
|
} |
|
|
} |
|
|
if (manager->mode == UDP_ONLY) { |
|
|
|
|
|
|
|
|
if (server->mode == NULL && manager->mode == UDP_ONLY) { |
|
|
int len = strlen(cmd); |
|
|
int len = strlen(cmd); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " -U"); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " -U"); |
|
|
} |
|
|
} |
|
|
if (manager->mode == TCP_AND_UDP) { |
|
|
|
|
|
|
|
|
if (server->mode == NULL && manager->mode == TCP_AND_UDP) { |
|
|
int len = strlen(cmd); |
|
|
int len = strlen(cmd); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " -u"); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " -u"); |
|
|
} |
|
|
} |
|
|
if (manager->fast_open) { |
|
|
|
|
|
|
|
|
if (server->fast_open[0] == 0 && manager->fast_open) { |
|
|
int len = strlen(cmd); |
|
|
int len = strlen(cmd); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " --fast-open"); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " --fast-open"); |
|
|
} |
|
|
} |
|
@ -163,11 +179,11 @@ construct_command_line(struct manager_ctx *manager, struct server *server) |
|
|
int len = strlen(cmd); |
|
|
int len = strlen(cmd); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " --mtu %d", manager->mtu); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " --mtu %d", manager->mtu); |
|
|
} |
|
|
} |
|
|
if (manager->plugin) { |
|
|
|
|
|
|
|
|
if (server->plugin == NULL && manager->plugin) { |
|
|
int len = strlen(cmd); |
|
|
int len = strlen(cmd); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " --plugin \"%s\"", manager->plugin); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " --plugin \"%s\"", manager->plugin); |
|
|
} |
|
|
} |
|
|
if (manager->plugin_opts) { |
|
|
|
|
|
|
|
|
if (server->plugin_opts == NULL && manager->plugin_opts) { |
|
|
int len = strlen(cmd); |
|
|
int len = strlen(cmd); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " --plugin-opts \"%s\"", manager->plugin_opts); |
|
|
snprintf(cmd + len, BUF_SIZE - len, " --plugin-opts \"%s\"", manager->plugin_opts); |
|
|
} |
|
|
} |
|
@ -264,6 +280,26 @@ get_server(char *buf, int len) |
|
|
if (value->type == json_string) { |
|
|
if (value->type == json_string) { |
|
|
strncpy(server->password, value->u.string.ptr, 128); |
|
|
strncpy(server->password, value->u.string.ptr, 128); |
|
|
} |
|
|
} |
|
|
|
|
|
} else if (strcmp(name, "method") == 0) { |
|
|
|
|
|
if (value->type == json_string) { |
|
|
|
|
|
server->method = strdup(value->u.string.ptr); |
|
|
|
|
|
} |
|
|
|
|
|
} else if (strcmp(name, "fast_open") == 0) { |
|
|
|
|
|
if (value->type == json_boolean) { |
|
|
|
|
|
strncpy(server->fast_open, (value->u.boolean ? "true" : "false"), 8); |
|
|
|
|
|
} |
|
|
|
|
|
} else if (strcmp(name, "plugin") == 0) { |
|
|
|
|
|
if (value->type == json_string) { |
|
|
|
|
|
server->plugin = strdup(value->u.string.ptr); |
|
|
|
|
|
} |
|
|
|
|
|
} else if (strcmp(name, "plugin_opts") == 0) { |
|
|
|
|
|
if (value->type == json_string) { |
|
|
|
|
|
server->plugin_opts = strdup(value->u.string.ptr); |
|
|
|
|
|
} |
|
|
|
|
|
} else if (strcmp(name, "mode") == 0) { |
|
|
|
|
|
if (value->type == json_string) { |
|
|
|
|
|
server->mode = strdup(value->u.string.ptr); |
|
|
|
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
LOGE("invalid data: %s", data); |
|
|
LOGE("invalid data: %s", data); |
|
|
break; |
|
|
break; |
|
@ -623,6 +659,7 @@ remove_server(char *prefix, char *port) |
|
|
cork_hash_table_delete(server_table, (void *)port, (void **)&old_port, (void **)&old_server); |
|
|
cork_hash_table_delete(server_table, (void *)port, (void **)&old_port, (void **)&old_server); |
|
|
|
|
|
|
|
|
if (old_server != NULL) { |
|
|
if (old_server != NULL) { |
|
|
|
|
|
destroy_server(old_server); |
|
|
ss_free(old_server); |
|
|
ss_free(old_server); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -647,7 +684,7 @@ manager_recv_cb(EV_P_ ev_io *w, int revents) |
|
|
{ |
|
|
{ |
|
|
struct manager_ctx *manager = (struct manager_ctx *)w; |
|
|
struct manager_ctx *manager = (struct manager_ctx *)w; |
|
|
socklen_t len; |
|
|
socklen_t len; |
|
|
size_t r; |
|
|
|
|
|
|
|
|
ssize_t r; |
|
|
struct sockaddr_un claddr; |
|
|
struct sockaddr_un claddr; |
|
|
char buf[BUF_SIZE]; |
|
|
char buf[BUF_SIZE]; |
|
|
|
|
|
|
|
@ -676,6 +713,7 @@ manager_recv_cb(EV_P_ ev_io *w, int revents) |
|
|
if (server == NULL || server->port[0] == 0 || server->password[0] == 0) { |
|
|
if (server == NULL || server->port[0] == 0 || server->password[0] == 0) { |
|
|
LOGE("invalid command: %s:%s", buf, get_data(buf, r)); |
|
|
LOGE("invalid command: %s:%s", buf, get_data(buf, r)); |
|
|
if (server != NULL) { |
|
|
if (server != NULL) { |
|
|
|
|
|
destroy_server(server); |
|
|
ss_free(server); |
|
|
ss_free(server); |
|
|
} |
|
|
} |
|
|
goto ERROR_MSG; |
|
|
goto ERROR_MSG; |
|
@ -683,6 +721,8 @@ manager_recv_cb(EV_P_ ev_io *w, int revents) |
|
|
|
|
|
|
|
|
remove_server(working_dir, server->port); |
|
|
remove_server(working_dir, server->port); |
|
|
int ret = add_server(manager, server); |
|
|
int ret = add_server(manager, server); |
|
|
|
|
|
destroy_server(server); |
|
|
|
|
|
ss_free(server); |
|
|
|
|
|
|
|
|
char *msg; |
|
|
char *msg; |
|
|
int msg_len; |
|
|
int msg_len; |
|
@ -704,12 +744,14 @@ manager_recv_cb(EV_P_ ev_io *w, int revents) |
|
|
if (server == NULL || server->port[0] == 0) { |
|
|
if (server == NULL || server->port[0] == 0) { |
|
|
LOGE("invalid command: %s:%s", buf, get_data(buf, r)); |
|
|
LOGE("invalid command: %s:%s", buf, get_data(buf, r)); |
|
|
if (server != NULL) { |
|
|
if (server != NULL) { |
|
|
|
|
|
destroy_server(server); |
|
|
ss_free(server); |
|
|
ss_free(server); |
|
|
} |
|
|
} |
|
|
goto ERROR_MSG; |
|
|
goto ERROR_MSG; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
remove_server(working_dir, server->port); |
|
|
remove_server(working_dir, server->port); |
|
|
|
|
|
destroy_server(server); |
|
|
ss_free(server); |
|
|
ss_free(server); |
|
|
|
|
|
|
|
|
char msg[3] = "ok"; |
|
|
char msg[3] = "ok"; |
|
|