Skip to content

Commit

Permalink
ss_local works on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Noisyfox committed Mar 27, 2017
1 parent e4e3245 commit f208f92
Show file tree
Hide file tree
Showing 11 changed files with 742 additions and 444 deletions.
3 changes: 2 additions & 1 deletion src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ int init_udprelay(const char *server_host, const char *server_port,
const ss_addr_t tunnel_addr,
#endif
#endif
int mtu, int timeout, const char *iface, const char *protocol, const char *protocol_param);
int mtu, int timeout, const char *iface,
cipher_env_t* cipher_env, const char *protocol, const char *protocol_param);

void free_udprelay(void);

Expand Down
2 changes: 1 addition & 1 deletion src/encrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ dump(char *tag, char *text, int len)

#endif

cipher_env_t cipher_env;
//cipher_env_t cipher_env;

static const char *supported_ciphers[CIPHER_NUM] = {
"table",
Expand Down
2 changes: 1 addition & 1 deletion src/encrypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,6 @@ int balloc(buffer_t *ptr, size_t capacity);
int brealloc(buffer_t *ptr, size_t len, size_t capacity);
void bfree(buffer_t *ptr);

extern cipher_env_t cipher_env;
//extern cipher_env_t cipher_env;

#endif // _ENCRYPT_H
256 changes: 168 additions & 88 deletions src/jconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,62 @@ parse_addr(const char *str, ss_addr_t *addr)
}
}

void parse_ss_server(ss_server_t *server, json_value* json) {
unsigned int i;

// TODO: set default value

for (i = 0; i < json->u.object.length; i++) {
char *name = json->u.object.values[i].name;
json_value *value = json->u.object.values[i].value;

if (strcmp(name, "id") == 0) {
server->id = to_string(value);
} else if (strcmp(name, "server") == 0) {
server->server = to_string(value);
} else if (strcmp(name, "server_port") == 0) {
check_json_value_type(value, json_integer,
"invalid config file: option 'server_port' must be an integer");
server->server_port = value->u.integer;
} else if (strcmp(name, "server_udp_port") == 0) { // SSR
check_json_value_type(value, json_integer,
"invalid config file: option 'server_udp_port' must be an integer");
server->server_udp_port = value->u.integer;
} else if (strcmp(name, "password") == 0) {
server->password = to_string(value);
} else if (strcmp(name, "method") == 0) {
server->method = to_string(value);
} else if (strcmp(name, "protocol") == 0) { // SSR
server->protocol = to_string(value);
} else if (strcmp(name, "protocol_param") == 0) { //SSR
server->protocol_param = to_string(value);
} else if (strcmp(name, "obfs") == 0) { // SSR
server->obfs = to_string(value);
} else if (strcmp(name, "obfs_param") == 0) { // SSR
server->obfs_param = to_string(value);
} else if (strcmp(name, "group") == 0) { // SSR
server->group = to_string(value);
} else if (strcmp(name, "enable") == 0) { // SSR
check_json_value_type(value, json_boolean,
"invalid config file: option 'enable' must be an boolean");
server->enable = value->u.boolean;
} else if (strcmp(name, "udp_over_tcp") == 0) { // SSR
check_json_value_type(value, json_boolean,
"invalid config file: option 'udp_over_tcp' must be an boolean");
server->udp_over_tcp = value->u.boolean;
}
}
}

jconf_t *
read_jconf(const char *file)
{
static jconf_t conf;

memset(&conf, 0, sizeof(jconf_t));

conf.conf_ver = CONF_VER_LEGACY; // try legacy version first

char *buf;
json_value *obj;

Expand Down Expand Up @@ -151,101 +200,132 @@ read_jconf(const char *file)
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;
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;

int match = 1;

// Legacy server config format
if (conf.conf_ver == CONF_VER_LEGACY) {
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.server_legacy.remote_addr + j);
ss_free(addr_str);
conf.server_legacy.remote_num = j + 1;
}
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) {
conf.server_legacy.remote_addr[0].host = to_string(value);
conf.server_legacy.remote_addr[0].port = NULL;
conf.server_legacy.remote_num = 1;
}
} else if (value->type == json_string) {
conf.remote_addr[0].host = to_string(value);
conf.remote_addr[0].port = NULL;
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;
} 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.server_legacy.port_password[j].port = ss_strndup(value->u.object.values[j].name,
value->u.object.values[j].name_length);
conf.server_legacy.port_password[j].password = to_string(v);
conf.server_legacy.port_password_num = j + 1;
}
}
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.server_legacy.remote_port = to_string(value);
} else if (strcmp(name, "local_address") == 0) {
conf.server_legacy.local_addr = to_string(value);
} else if (strcmp(name, "local_port") == 0) {
conf.server_legacy.local_port = to_string(value);
} else if (strcmp(name, "password") == 0) {
conf.server_legacy.password = to_string(value);
} else if (strcmp(name, "auth") == 0) {
LOGI("auth is deprecated, ignored");
} else if (strcmp(name, "protocol") == 0) { // SSR
conf.server_legacy.protocol = to_string(value);
} else if (strcmp(name, "protocol_param") == 0) { //SSR
conf.server_legacy.protocol_param = to_string(value);
} else if (strcmp(name, "method") == 0) {
conf.server_legacy.method = to_string(value);
} else if (strcmp(name, "obfs") == 0) { // SSR
conf.server_legacy.obfs = to_string(value);
} else if (strcmp(name, "obfs_param") == 0) { // SSR
conf.server_legacy.obfs_param = to_string(value);
} else {
match = 0;
}
}
if (!match) {
if(strcmp(name, "servers") == 0) {
if(conf.conf_ver == CONF_VER_LEGACY) {
memset(&conf.server_new_1, 0, sizeof(conf.server_new_1));
conf.conf_ver = CONF_VER_1;
}

if (value->type == json_array) {
for (j = 0; j < value->u.array.length; j++) {
if (conf.server_new_1.server_num >= MAX_SERVER_NUM) {
LOGI("Max servers exceed, ignore remain server defines.");
break;
}
json_value *v = value->u.array.values[j];

if(v->type == json_object) {
parse_ss_server(&conf.server_new_1.servers[conf.server_new_1.server_num], v);
conf.server_new_1.server_num++;
}
}
}
} 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, "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, "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, "tunnel_address") == 0) {
conf.tunnel_address = to_string(value);
} else if (strcmp(name, "mode") == 0) {
char *mode_str = to_string(value);

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;
}
} 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, "protocol") == 0) { // SSR
conf.protocol = to_string(value);
} else if (strcmp(name, "protocol_param") == 0) { //SSR
conf.protocol_param = to_string(value);
} else if (strcmp(name, "method") == 0) {
conf.method = to_string(value);
} else if (strcmp(name, "obfs") == 0) { // SSR
conf.obfs = to_string(value);
} else if (strcmp(name, "obfs_param") == 0) { // SSR
conf.obfs_param = 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, "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, "auth") == 0) {
LOGI("auth is deprecated, ignored");
} 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, "tunnel_address") == 0) {
conf.tunnel_address = to_string(value);
} else if (strcmp(name, "mode") == 0) {
char *mode_str = to_string(value);

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;
}
}
} else {
Expand Down
37 changes: 37 additions & 0 deletions src/jconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#define MAX_PORT_NUM 1024
#define MAX_REMOTE_NUM 10
#define MAX_SERVER_NUM 10
#define MAX_CONF_SIZE 128 * 1024
#define MAX_DNS_NUM 4
#define MAX_CONNECT_TIMEOUT 10
Expand All @@ -44,6 +45,26 @@ typedef struct {
char *password;
} ss_port_password_t;

typedef struct {
// address from input (cmd or config file)
char *server;
int server_port;
int server_udp_port;

char *password; // raw password
char *method;

char *protocol;
char *protocol_param;
char *obfs;
char *obfs_param;

char *id;
char *group;
int enable;
int udp_over_tcp;
} ss_server_t;

typedef struct {
int remote_num;
ss_addr_t remote_addr[MAX_REMOTE_NUM];
Expand All @@ -58,6 +79,22 @@ typedef struct {
char *method;
char *obfs; // SSR
char *obfs_param; // SSR
} ss_server_legacy_t;

typedef struct {
size_t server_num;
ss_server_t servers[MAX_SERVER_NUM];
} ss_server_new_1_t;

#define CONF_VER_LEGACY 0
#define CONF_VER_1 1

typedef struct {
int conf_ver; // 0 for legacy, > 0 for server_new_X
union {
ss_server_legacy_t server_legacy;
ss_server_new_1_t server_new_1;
};
char *timeout;
char *user;
int fast_open;
Expand Down
Loading

0 comments on commit f208f92

Please sign in to comment.