Skip to content

Commit

Permalink
One step to support IPv6
Browse files Browse the repository at this point in the history
Since this commit, the config file will not be compatible with earlier
versions. With this update, "redsocks" should support proxy servers at
IPv6 address.
  • Loading branch information
semigodking committed Sep 25, 2019
1 parent b9cafa9 commit 3f41aa2
Show file tree
Hide file tree
Showing 10 changed files with 352 additions and 314 deletions.
11 changes: 8 additions & 3 deletions autoproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,9 +708,14 @@ static int auto_connect_relay(redsocks_client *client)
aclient->quick_check = 1;
}
/* connect to target directly without going through proxy */
client->relay = red_connect_relay(config->interface, &client->destaddr,
NULL, auto_relay_connected, auto_event_error, client,
&tv);
client->relay = red_connect_relay(
config->interface,
(struct sockaddr *)&client->destaddr,
NULL,
auto_relay_connected,
auto_event_error,
client,
&tv);
if (!client->relay) {
// Failed to connect to destination directly, try again via proxy.
return auto_retry(client, 0);
Expand Down
10 changes: 8 additions & 2 deletions direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,14 @@ static int direct_connect_relay(redsocks_client *client)
struct timeval tv = {client->instance->config.timeout, 0};

// Allowing binding relay socket to specified IP for outgoing connections
client->relay = red_connect_relay(interface, &client->destaddr, NULL,
redsocks_relay_connected, redsocks_event_error, client, &tv);
client->relay = red_connect_relay(
interface,
(struct sockaddr *)&client->destaddr,
NULL,
redsocks_relay_connected,
redsocks_event_error,
client,
&tv);
if (!client->relay)
{
redsocks_log_errno(client, LOG_ERR, "red_connect_relay");
Expand Down
26 changes: 15 additions & 11 deletions redsocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ static parser_entry redsocks_entries[] =
{ .key = "local_ip", .type = pt_in_addr },
{ .key = "local_port", .type = pt_uint16 },
{ .key = "interface", .type = pt_pchar },
{ .key = "ip", .type = pt_in_addr },
{ .key = "port", .type = pt_uint16 },
{ .key = "relay", .type = pt_pchar },
{ .key = "type", .type = pt_pchar },
{ .key = "login", .type = pt_pchar },
{ .key = "password", .type = pt_pchar },
Expand Down Expand Up @@ -156,8 +155,6 @@ static int redsocks_onenter(parser_section *section)
INIT_LIST_HEAD(&instance->clients);
instance->config.bindaddr.sin_family = AF_INET;
instance->config.bindaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
instance->config.relayaddr.sin_family = AF_INET;
instance->config.relayaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
/* Default value can be checked in run-time, but I doubt anyone needs that.
* Linux: sysctl net.core.somaxconn
* FreeBSD: sysctl kern.ipc.somaxconn */
Expand All @@ -172,8 +169,7 @@ static int redsocks_onenter(parser_section *section)
(strcmp(entry->key, "local_ip") == 0) ? (void*)&instance->config.bindaddr.sin_addr :
(strcmp(entry->key, "local_port") == 0) ? (void*)&instance->config.bindaddr.sin_port :
(strcmp(entry->key, "interface") == 0) ? (void*)&instance->config.interface :
(strcmp(entry->key, "ip") == 0) ? (void*)&instance->config.relayaddr.sin_addr :
(strcmp(entry->key, "port") == 0) ? (void*)&instance->config.relayaddr.sin_port :
(strcmp(entry->key, "relay") == 0) ? (void*)&instance->config.relay :
(strcmp(entry->key, "type") == 0) ? (void*)&instance->config.type :
(strcmp(entry->key, "login") == 0) ? (void*)&instance->config.login :
(strcmp(entry->key, "password") == 0) ? (void*)&instance->config.password :
Expand All @@ -200,10 +196,17 @@ static int redsocks_onexit(parser_section *section)
for (parser_entry *entry = &section->entries[0]; entry->key; entry++)
entry->addr = NULL;

// Parse and update relay address
struct sockaddr * addr = (struct sockaddr *)&instance->config.relayaddr;
int addr_size = sizeof(instance->config.relayaddr);
if (instance->config.relay) {
if (evutil_parse_sockaddr_port(instance->config.relay, addr, &addr_size))
err = "invalid relay address";
}

instance->config.bindaddr.sin_port = htons(instance->config.bindaddr.sin_port);
instance->config.relayaddr.sin_port = htons(instance->config.relayaddr.sin_port);

if (instance->config.type) {
if (!err && instance->config.type) {
relay_subsys **ss;
FOREACH(ss, relay_subsystems) {
if (!strcmp((*ss)->name, instance->config.type)) {
Expand Down Expand Up @@ -278,8 +281,8 @@ void redsocks_touch_client(redsocks_client *client)

static inline const char* bufname(redsocks_client *client, struct bufferevent *buf)
{
assert(buf == client->client || buf == client->relay);
return buf == client->client ? "client" : "relay";
assert(buf == client->client || buf == client->relay);
return buf == client->client ? "client" : "relay";
}

static void redsocks_relay_readcb(redsocks_client *client, struct bufferevent *from, struct bufferevent *to)
Expand Down Expand Up @@ -677,7 +680,8 @@ int redsocks_connect_relay(redsocks_client *client)
tv.tv_usec = 0;

// Allowing binding relay socket to specified IP for outgoing connections
client->relay = red_connect_relay(interface, &client->instance->config.relayaddr,
client->relay = red_connect_relay(interface,
(struct sockaddr *)&client->instance->config.relayaddr,
NULL,
redsocks_relay_connected,
redsocks_event_error, client, &tv);
Expand Down
17 changes: 12 additions & 5 deletions redsocks.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,18 @@ redsocks {
// max_accept_backoff = 60000;

// `ip' and `port' are IP and tcp-port of proxy-server
// You can also use hostname instead of IP, only one (random)
// address of multihomed host will be used.
// The two fields are meaningless when proxy type is 'direct'.
ip = example.org;
port = 1080;
// These two parameters are removed to support IPv6.

// `relay' is IP address and port of proxy-server. Domain name is not
// supported yet.
// Can be:
// [IPv6Address]:port
// [IPv6Address]
// IPv6Address
// IPv4Address:port
// IPv4Address
// If no port is given, 0 is used. Usually, a valid port is required.
relay = "127.0.0.1:1080";

// known types: socks4, socks5, http-connect, http-relay
// New types: direct, shadowsocks, https-connect
Expand Down
3 changes: 2 additions & 1 deletion redsocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ typedef struct relay_subsys_t {

typedef struct redsocks_config_t {
struct sockaddr_in bindaddr;
struct sockaddr_in relayaddr;
struct sockaddr_storage relayaddr;
char *relay;
char *type;
char *login;
char *password;
Expand Down
13 changes: 10 additions & 3 deletions shadowsocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,16 @@ static int ss_connect_relay(redsocks_client *client)

tv.tv_sec = client->instance->config.timeout;
tv.tv_usec = 0;
client->relay = red_connect_relay_tfo(interface, &client->instance->config.relayaddr,
NULL, ss_relay_connected, redsocks_event_error, client,
&tv, &buff[0], &sz);
client->relay = red_connect_relay_tfo(
interface,
(struct sockaddr *)&client->instance->config.relayaddr,
NULL,
ss_relay_connected,
redsocks_event_error,
client,
&tv,
&buff[0],
&sz);

if (!client->relay) {
redsocks_drop_client(client);
Expand Down
Loading

0 comments on commit 3f41aa2

Please sign in to comment.