From 7a428d0fc72e50ec98f933418f6ebff2b9e97514 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Tue, 27 Aug 2019 18:31:25 +0800 Subject: [PATCH] Clean up --- jconf.c | 351 -------------------------------------------------------- 1 file changed, 351 deletions(-) delete mode 100644 jconf.c diff --git a/jconf.c b/jconf.c deleted file mode 100644 index bf36a578..00000000 --- a/jconf.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * jconf.c - Parse the JSON format config file - * - * Copyright (C) 2013 - 2018, Max Lv - * - * This file is part of the shadowsocks-libev. - * shadowsocks-libev is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * shadowsocks-libev is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with shadowsocks-libev; see the file COPYING. If not, see - * . - */ - -#include -#include -#include -#include -#include - -#include "netutils.h" -#include "utils.h" -#include "jconf.h" -#include "json.h" -#include "string.h" - -#include - -#define check_json_value_type(value, expected_type, message) \ - do { \ - if ((value)->type != (expected_type)) \ - FATAL((message)); \ - } while (0) - -static char * -to_string(const json_value *value) -{ - if (value->type == json_string) { - return ss_strndup(value->u.string.ptr, value->u.string.length); - } else if (value->type == json_integer) { - return strdup(ss_itoa(value->u.integer)); - } else if (value->type == json_null) { - return NULL; - } else { - LOGE("%d", value->type); - FATAL("Invalid config format."); - } - return 0; -} - -void -free_addr(ss_addr_t *addr) -{ - ss_free(addr->host); - ss_free(addr->port); -} - -void -parse_addr(const char *str_in, ss_addr_t *addr) -{ - if (str_in == NULL) - return; - - int ipv6 = 0, ret = -1, n = 0, len; - char *pch; - char *str = strdup(str_in); - len = strlen(str_in); - - struct cork_ip ip; - if (cork_ip_init(&ip, str) != -1) { - addr->host = str; - addr->port = NULL; - return; - } - - pch = strchr(str, ':'); - while (pch != NULL) { - n++; - ret = pch - str; - pch = strchr(pch + 1, ':'); - } - - if (n > 1) { - ipv6 = 1; - if (str[ret - 1] != ']') { - ret = -1; - } - } - - if (ret == -1) { - if (ipv6) { - addr->host = ss_strndup(str + 1, strlen(str) - 2); - } else { - addr->host = strdup(str); - } - addr->port = NULL; - } else { - if (ipv6) { - addr->host = ss_strndup(str + 1, ret - 2); - } else { - addr->host = ss_strndup(str, ret); - } - if (ret < len - 1) - { - addr->port = strdup(str + ret + 1); - } else { - addr->port = NULL; - } - } - - free(str); -} - -static int -parse_dscp(char *str) -{ - size_t str_len = strlen(str); - - // Pre-defined values (EF, CSx, AFxy) - if (str_len == 2 && strcasecmp(str, "EF") == 0) { - return DSCP_EF; - } - - if (str_len == DSCP_CS_LEN && strncasecmp(str, "CS", 2) == 0) { - if (str[2] >= '0' && str[2] <= '7') { - // CSx = 8x - return (str[2] - '0') << 3; - } - } - - if (str_len == DSCP_AF_LEN && strncasecmp(str, "AF", 2) == 0) { - if (str[2] >= '1' && str[2] <= '4' && str[3] >= '1' && str[3] <= '3') { - // AFxy = 8x + 2y - return ((str[2] - '0') << 3) | ((str[3] - '0') << 1); - } - } - - // Manual hexadecimal mode (0xYZ) - char *endptr; - int dscp = (int)strtol(str, &endptr, 0); - if (*endptr == '\0' && dscp >= DSCP_MIN && dscp <= DSCP_MAX) { - return dscp; - } - - LOGE("Invalid DSCP value (%s)", str); - return DSCP_DEFAULT; -} - -jconf_t * -read_jconf(const char *file) -{ - static jconf_t conf; - - memset(&conf, 0, sizeof(jconf_t)); - - char *buf; - json_value *obj; - - FILE *f = fopen(file, "rb"); - if (f == NULL) { - FATAL("Invalid config path."); - } - - fseek(f, 0, SEEK_END); - long pos = ftell(f); - fseek(f, 0, SEEK_SET); - - if (pos < 0) { - FATAL("Invalid config path."); - } - - if (pos >= MAX_CONF_SIZE) { - FATAL("Too large config file."); - } - - buf = ss_malloc(pos + 1); - if (buf == NULL) { - FATAL("No enough memory."); - } - - int nread = fread(buf, pos, 1, f); - if (!nread) { - FATAL("Failed to read the config file."); - } - fclose(f); - - buf[pos] = '\0'; // end of string - - json_settings settings = { 0UL, 0, NULL, NULL, NULL }; - char error_buf[512]; - obj = json_parse_ex(&settings, buf, pos, error_buf); - - if (obj == NULL) { - FATAL(error_buf); - } - - if (obj->type == json_object) { - unsigned int i, j; - for (i = 0; i < obj->u.object.length; i++) { - char *name = obj->u.object.values[i].name; - json_value *value = obj->u.object.values[i].value; - if (strcmp(name, "server") == 0) { - if (value->type == json_array) { - for (j = 0; j < value->u.array.length; j++) { - if (j >= MAX_REMOTE_NUM) { - break; - } - json_value *v = value->u.array.values[j]; - char *addr_str = to_string(v); - parse_addr(addr_str, conf.remote_addr + j); - ss_free(addr_str); - conf.remote_num = j + 1; - } - } else if (value->type == json_string) { - parse_addr(to_string(value), conf.remote_addr); - conf.remote_num = 1; - } - } else if (strcmp(name, "port_password") == 0) { - if (value->type == json_object) { - for (j = 0; j < value->u.object.length; j++) { - if (j >= MAX_PORT_NUM) { - break; - } - json_value *v = value->u.object.values[j].value; - if (v->type == json_string) { - conf.port_password[j].port = ss_strndup(value->u.object.values[j].name, - value->u.object.values[j].name_length); - conf.port_password[j].password = to_string(v); - conf.port_password_num = j + 1; - } - } - } - } else if (strcmp(name, "server_port") == 0) { - conf.remote_port = to_string(value); - } else if (strcmp(name, "local_address") == 0) { - conf.local_addr = to_string(value); - } else if (strcmp(name, "local_port") == 0) { - conf.local_port = to_string(value); - } else if (strcmp(name, "password") == 0) { - conf.password = to_string(value); - } else if (strcmp(name, "key") == 0) { - conf.key = to_string(value); - } else if (strcmp(name, "method") == 0) { - conf.method = to_string(value); - } else if (strcmp(name, "timeout") == 0) { - conf.timeout = to_string(value); - } else if (strcmp(name, "user") == 0) { - conf.user = to_string(value); - } else if (strcmp(name, "plugin") == 0) { - conf.plugin = to_string(value); - if (conf.plugin && strlen(conf.plugin) == 0) { - ss_free(conf.plugin); - conf.plugin = NULL; - } - } else if (strcmp(name, "plugin_opts") == 0) { - conf.plugin_opts = to_string(value); - } else if (strcmp(name, "fast_open") == 0) { - check_json_value_type(value, json_boolean, - "invalid config file: option 'fast_open' must be a boolean"); - conf.fast_open = value->u.boolean; - } else if (strcmp(name, "reuse_port") == 0) { - check_json_value_type(value, json_boolean, - "invalid config file: option 'reuse_port' must be a boolean"); - conf.reuse_port = value->u.boolean; - } else if (strcmp(name, "auth") == 0) { - FATAL("One time auth has been deprecated. Try AEAD ciphers instead."); - } else if (strcmp(name, "nofile") == 0) { - check_json_value_type(value, json_integer, - "invalid config file: option 'nofile' must be an integer"); - conf.nofile = value->u.integer; - } else if (strcmp(name, "nameserver") == 0) { - conf.nameserver = to_string(value); - } else if (strcmp(name, "dscp") == 0) { - if (value->type == json_object) { - for (j = 0; j < value->u.object.length; j++) { - if (j >= MAX_DSCP_NUM) { - break; - } - json_value *v = value->u.object.values[j].value; - if (v->type == json_string) { - int dscp = parse_dscp(to_string(v)); - char *port = ss_strndup(value->u.object.values[j].name, - value->u.object.values[j].name_length); - conf.dscp[j].port = port; - conf.dscp[j].dscp = dscp; - conf.dscp_num = j + 1; - } - } - } - } else if (strcmp(name, "tunnel_address") == 0) { - conf.tunnel_address = to_string(value); - } else if (strcmp(name, "mode") == 0) { - char *mode_str = to_string(value); - - if (mode_str == NULL) - conf.mode = TCP_ONLY; - else if (strcmp(mode_str, "tcp_only") == 0) - conf.mode = TCP_ONLY; - else if (strcmp(mode_str, "tcp_and_udp") == 0) - conf.mode = TCP_AND_UDP; - else if (strcmp(mode_str, "udp_only") == 0) - conf.mode = UDP_ONLY; - else - LOGI("ignore unknown mode: %s, use tcp_only as fallback", - mode_str); - - ss_free(mode_str); - } else if (strcmp(name, "mtu") == 0) { - check_json_value_type(value, json_integer, - "invalid config file: option 'mtu' must be an integer"); - conf.mtu = value->u.integer; - } else if (strcmp(name, "mptcp") == 0) { - check_json_value_type(value, json_boolean, - "invalid config file: option 'mptcp' must be a boolean"); - conf.mptcp = value->u.boolean; - } else if (strcmp(name, "ipv6_first") == 0) { - check_json_value_type(value, json_boolean, - "invalid config file: option 'ipv6_first' must be a boolean"); - conf.ipv6_first = value->u.boolean; -#ifdef HAS_SYSLOG - } else if (strcmp(name, "use_syslog") == 0) { - check_json_value_type(value, json_boolean, - "invalid config file: option 'use_syslog' must be a boolean"); - use_syslog = value->u.boolean; -#endif - } else if (strcmp(name, "no_delay") == 0) { - check_json_value_type( - value, json_boolean, - "invalid config file: option 'no_delay' must be a boolean"); - conf.no_delay = value->u.boolean; - } else if (strcmp(name, "workdir") == 0) { - conf.workdir = to_string(value); - } else if (strcmp(name, "acl") == 0) { - conf.acl = to_string(value); - } - } - } else { - FATAL("Invalid config file"); - } - - ss_free(buf); - json_value_free(obj); - return &conf; -}