Browse Source

Add -6 option for #942

pull/946/head
Max Lv 8 years ago
parent
commit
5cd294879b
10 changed files with 62 additions and 31 deletions
  1. 3
      src/acl.c
  2. 2
      src/cache.c
  3. 25
      src/local.c
  4. 4
      src/manager.c
  5. 8
      src/netutils.c
  6. 4
      src/netutils.h
  7. 16
      src/redir.c
  8. 9
      src/server.c
  9. 4
      src/tls.c
  10. 18
      src/tunnel.c

3
src/acl.c

@ -134,7 +134,8 @@ init_firewall()
fp = popen(cli, "r");
if (fp == NULL)
return -1;
if (pclose(fp) == 0) mode = IPTABLES_MODE;
if (pclose(fp) == 0)
mode = IPTABLES_MODE;
}
sprintf(chain_name, "SHADOWSOCKS_LIBEV_%d", getpid());

2
src/cache.c

@ -283,7 +283,7 @@ cache_insert(struct cache *cache, char *key, size_t key_len, void *data)
entry->key = ss_malloc(key_len);
memcpy(entry->key, key, key_len);
entry->data = data;
entry->ts = ev_time();
entry->ts = ev_time();
HASH_ADD_KEYPTR(hh, cache->entries, entry->key, key_len, entry);
if (HASH_COUNT(cache->entries) >= cache->max_entries) {

25
src/local.c

@ -91,8 +91,9 @@ ev_tstamp last = 0;
char *prefix;
#endif
static int acl = 0;
static int mode = TCP_ONLY;
static int acl = 0;
static int mode = TCP_ONLY;
static int ipv6first = 0;
static int fast_open = 0;
#ifdef HAVE_SETRLIMIT
@ -634,9 +635,9 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
int err;
memset(&storage, 0, sizeof(struct sockaddr_storage));
if (atyp == 1 || atyp == 4) {
err = get_sockaddr(ip, port, &storage, 0);
err = get_sockaddr(ip, port, &storage, 0, ipv6first);
} else {
err = get_sockaddr(host, port, &storage, 1);
err = get_sockaddr(host, port, &storage, 1, ipv6first);
}
if (err != -1) {
remote = create_remote(server->listener, (struct sockaddr *)&storage);
@ -737,6 +738,7 @@ stat_update_cb()
last = now;
}
}
#endif
static void
@ -1154,10 +1156,10 @@ main(int argc, char **argv)
USE_TTY();
#ifdef ANDROID
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:P:huUvVA",
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:P:huUvVA6",
long_options, &option_index)) != -1) {
#else
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:huUvA",
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:huUvA6",
long_options, &option_index)) != -1) {
#endif
switch (c) {
@ -1235,6 +1237,9 @@ main(int argc, char **argv)
case 'A':
auth = 1;
break;
case '6':
ipv6first = 1;
break;
#ifdef ANDROID
case 'V':
vpn = 1;
@ -1352,6 +1357,10 @@ main(int argc, char **argv)
#endif
}
if (ipv6first) {
LOGI("resolving hostname to IPv6 address first");
}
if (auth) {
LOGI("onetime authentication enabled");
}
@ -1380,7 +1389,7 @@ main(int argc, char **argv)
remote_addr[i].port;
struct sockaddr_storage *storage = ss_malloc(sizeof(struct sockaddr_storage));
memset(storage, 0, sizeof(struct sockaddr_storage));
if (get_sockaddr(host, port, storage, 1) == -1) {
if (get_sockaddr(host, port, storage, 1, ipv6first) == -1) {
FATAL("failed to resolve the provided hostname");
}
listen_ctx.remote_addr[i] = (struct sockaddr *)storage;
@ -1536,7 +1545,7 @@ start_ss_local_server(profile_t profile)
struct sockaddr_storage *storage = ss_malloc(sizeof(struct sockaddr_storage));
memset(storage, 0, sizeof(struct sockaddr_storage));
if (get_sockaddr(remote_host, remote_port_str, storage, 1) == -1) {
if (get_sockaddr(remote_host, remote_port_str, storage, 1, ipv6first) == -1) {
return -1;
}

4
src/manager.c

@ -618,7 +618,7 @@ main(int argc, char **argv)
int mtu = 0;
#ifdef HAVE_SETRLIMIT
static int nofile = 0;
static int nofile = 0;
#endif
int server_num = 0;
@ -838,7 +838,7 @@ static int nofile = 0;
manager.nameserver_num = nameserver_num;
manager.mtu = mtu;
#ifdef HAVE_SETRLIMIT
manager.nofile = nofile;
manager.nofile = nofile;
#endif
// initialize ev loop

8
src/netutils.c

@ -118,7 +118,9 @@ bind_to_address(int socket_fd, const char *host)
}
ssize_t
get_sockaddr(char *host, char *port, struct sockaddr_storage *storage, int block)
get_sockaddr(char *host, char *port,
struct sockaddr_storage *storage, int block,
int ipv6first)
{
struct cork_ip ip;
if (cork_ip_init(&ip, host) != -1) {
@ -167,8 +169,9 @@ get_sockaddr(char *host, char *port, struct sockaddr_storage *storage, int block
return -1;
}
int prefer_af = ipv6first ? AF_INET6 : AF_INET;
for (rp = result; rp != NULL; rp = rp->ai_next)
if (rp->ai_family == AF_INET) {
if (rp->ai_family == prefer_af) {
memcpy(storage, rp->ai_addr, sizeof(struct sockaddr_in));
break;
}
@ -299,4 +302,3 @@ validate_hostname(const char *hostname, const int hostname_len)
return 1;
}

4
src/netutils.h

@ -61,7 +61,9 @@
#define INET6_SIZE 16
size_t get_sockaddr_len(struct sockaddr *addr);
ssize_t get_sockaddr(char *host, char *port, struct sockaddr_storage *storage, int block);
ssize_t get_sockaddr(char *host, char *port,
struct sockaddr_storage *storage, int block,
int ipv6first);
int set_reuseport(int socket);
#ifdef SET_INTERFACE

16
src/redir.c

@ -86,8 +86,9 @@ static void close_and_free_server(EV_P_ server_t *server);
int verbose = 0;
int keep_resolving = 1;
static int mode = TCP_ONLY;
static int auth = 0;
static int ipv6first = 0;
static int mode = TCP_ONLY;
static int auth = 0;
#ifdef HAVE_SETRLIMIT
static int nofile = 0;
#endif
@ -781,7 +782,7 @@ main(int argc, char **argv)
USE_TTY();
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:c:b:a:n:huUvA",
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:c:b:a:n:huUvA6",
long_options, &option_index)) != -1) {
switch (c) {
case 0:
@ -850,6 +851,9 @@ main(int argc, char **argv)
case 'A':
auth = 1;
break;
case '6':
ipv6first = 1;
break;
case '?':
// The option character is not recognized.
LOGE("Unrecognized option: %s", optarg);
@ -946,6 +950,10 @@ main(int argc, char **argv)
daemonize(pid_path);
}
if (ipv6first) {
LOGI("resolving hostname to IPv6 address first");
}
if (auth) {
LOGI("onetime authentication enabled");
}
@ -970,7 +978,7 @@ main(int argc, char **argv)
remote_addr[i].port;
struct sockaddr_storage *storage = ss_malloc(sizeof(struct sockaddr_storage));
memset(storage, 0, sizeof(struct sockaddr_storage));
if (get_sockaddr(host, port, storage, 1) == -1) {
if (get_sockaddr(host, port, storage, 1, ipv6first) == -1) {
FATAL("failed to resolve the provided hostname");
}
listen_ctx.remote_addr[i] = (struct sockaddr *)storage;

9
src/server.c

@ -183,7 +183,7 @@ stat_update_cb(EV_P_ ev_timer *watcher, int revents)
} else {
struct sockaddr_storage storage;
memset(&storage, 0, sizeof(struct sockaddr_storage));
if (get_sockaddr(ip_addr.host, ip_addr.port, &storage, 0) == -1) {
if (get_sockaddr(ip_addr.host, ip_addr.port, &storage, 0, ipv6first) == -1) {
ERROR("failed to parse the manager addr");
return;
}
@ -302,16 +302,16 @@ get_peer_name(int fd)
return peer_name;
}
#ifdef __linux__
static void
set_linger(int fd)
{
struct linger so_linger;
so_linger.l_onoff = 1;
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
setsockopt(fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger);
}
#endif
static void
@ -708,7 +708,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
ss_free(server->header_buf);
server->stage = 2;
} else {
if (ret == -1) server->stage = -1;
if (ret == -1)
server->stage = -1;
server->buf->len = 0;
server->buf->idx = 0;
return;

4
src/tls.c

@ -121,7 +121,7 @@ parse_tls_header(const char *data, size_t data_len, char **hostname)
if (tls_version_major < 3) {
if (verbose)
LOGI("Received SSL %d.%d handshake which can not support SNI.",
tls_version_major, tls_version_minor);
tls_version_major, tls_version_minor);
return -2;
}
@ -251,7 +251,7 @@ parse_server_name_extension(const char *data, size_t data_len,
default:
if (verbose)
LOGI("Unknown server name extension name type: %d",
data[pos]);
data[pos]);
}
pos += 3 + len;
}

18
src/tunnel.c

@ -93,8 +93,9 @@ char *prefix;
int verbose = 0;
int keep_resolving = 1;
static int mode = TCP_ONLY;
static int auth = 0;
static int ipv6first = 0;
static int mode = TCP_ONLY;
static int auth = 0;
#ifdef HAVE_SETRLIMIT
static int nofile = 0;
#endif
@ -750,10 +751,10 @@ main(int argc, char **argv)
USE_TTY();
#ifdef ANDROID
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:L:a:n:P:huUvVA",
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:L:a:n:P:huUvVA6",
long_options, &option_index)) != -1) {
#else
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:L:a:n:huUvA",
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:L:a:n:huUvA6",
long_options, &option_index)) != -1) {
#endif
switch (c) {
@ -829,6 +830,9 @@ main(int argc, char **argv)
case 'A':
auth = 1;
break;
case '6':
ipv6first = 1;
break;
#ifdef ANDROID
case 'V':
vpn = 1;
@ -939,6 +943,10 @@ main(int argc, char **argv)
daemonize(pid_path);
}
if (ipv6first) {
LOGI("resolving hostname to IPv6 address first");
}
if (auth) {
LOGI("onetime authentication enabled");
}
@ -975,7 +983,7 @@ main(int argc, char **argv)
remote_addr[i].port;
struct sockaddr_storage *storage = ss_malloc(sizeof(struct sockaddr_storage));
memset(storage, 0, sizeof(struct sockaddr_storage));
if (get_sockaddr(host, port, storage, 1) == -1) {
if (get_sockaddr(host, port, storage, 1, ipv6first) == -1) {
FATAL("failed to resolve the provided hostname");
}
listen_ctx.remote_addr[i] = (struct sockaddr *)storage;

Loading…
Cancel
Save