Skip to content

Commit

Permalink
One more step to support IPv6
Browse files Browse the repository at this point in the history
NOTE: not verified
  • Loading branch information
semigodking committed Sep 26, 2019
1 parent 3f41aa2 commit ea2b56a
Show file tree
Hide file tree
Showing 23 changed files with 362 additions and 265 deletions.
41 changes: 14 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,8 @@ To use the autoproxy feature, please change the redsocks section in
configuration file like this:

redsocks {
local_ip = 192.168.1.1;
local_port = 1081;
ip = 192.168.1.1;
port = 9050;
bind = "192.168.1.1:1081";
relay = "192.168.1.1:9050";
type = socks5; // I use socks5 proxy for GFW'ed IP
autoproxy = 1; // I want autoproxy feature enabled on this section.
// timeout is meaningful when 'autoproxy' is non-zero.
Expand All @@ -114,8 +112,7 @@ all blocked traffic pass through via VPN connection while normal traffic
pass through via default internet connection.

redsocks {
local_ip = 192.168.1.1;
local_port = 1080;
bind = "192.168.1.1:1081";
interface = tun0; // Outgoing interface for blocked traffic
type = direct;
timeout = 13;
Expand All @@ -127,11 +124,9 @@ Similar like other redsocks section. The encryption method is specified
by field 'login'.

redsocks {
local_ip = 192.168.1.1;
local_port = 1080;
bind = "192.168.1.1:1080";
type = shadowsocks;
ip = 192.168.1.1;
port = 8388;
relay = "192.168.1.1:8388";
timeout = 13;
autoproxy = 1;
login = "aes-128-cfb"; // field 'login' is reused as encryption
Expand All @@ -140,15 +135,12 @@ by field 'login'.
}

redudp {
local_ip = 127.0.0.1;
local_port = 1053;
ip = your.ss-server.com;
port = 443;
bind = "127.0.0.1:1053";
relay = "123.123.123.123:1082";
type = shadowsocks;
login = rc4-md5;
password = "ss server password";
dest_ip = 8.8.8.8;
dest_port = 53;
dest = "8.8.8.8:53";
udp_timeout = 3;
}

Expand Down Expand Up @@ -191,10 +183,8 @@ Suppose your goagent local proxy is running at the same server as redsocks2,
The configuration for forwarding connections to GoAgent is like below:

redsocks {
local_ip = 192.168.1.1;
local_port = 1081; //HTTP should be redirect to this port.
ip = 192.168.1.1;
port = 8080;
bind = "192.168.1.1:1081"; //HTTP should be redirect to this port.
relay = "192.168.1.1:8080";
type = http-relay; // Must be 'htt-relay' for HTTP traffic.
autoproxy = 1; // I want autoproxy feature enabled on this section.
// timeout is meaningful when 'autoproxy' is non-zero.
Expand All @@ -204,10 +194,8 @@ The configuration for forwarding connections to GoAgent is like below:
timeout = 13;
}
redsocks {
local_ip = 192.168.1.1;
local_port = 1082; // HTTPS should be redirect to this port.
ip = 192.168.1.1;
port = 8080;
bind = "192.168.1.1:1082"; //HTTPS should be redirect to this port.
relay = "192.168.1.1:8080";
type = http-connect; // Must be 'htt-connect' for HTTPS traffic.
autoproxy = 1; // I want autoproxy feature enabled on this section.
// timeout is meaningful when 'autoproxy' is non-zero.
Expand All @@ -226,9 +214,8 @@ with the following config section.
// Transform UDP DNS requests into TCP DNS requests.
// You can also redirect connections to external TCP DNS server to
// REDSOCKS transparent proxy via iptables.
local_ip = 192.168.1.1; // Local server to act as DNS server
local_port = 1053; // UDP port to receive UDP DNS requests
tcpdns1 = 8.8.4.4; // DNS server that supports TCP DNS requests
bind = "192.168.1.1:1053"; // Local server to act as DNS server
tcpdns1 = "8.8.4.4:53"; // DNS server that supports TCP DNS requests
tcpdns2 = 8.8.8.8; // DNS server that supports TCP DNS requests
timeout = 4; // Timeout value for TCP DNS requests
}
Expand Down
20 changes: 12 additions & 8 deletions autoproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ static void on_connection_confirmed(redsocks_client *client)
{
redsocks_log_error(client, LOG_DEBUG, "IP Confirmed");

cache_del_addr(&client->destaddr);
if (client->destaddr.ss_family == AF_INET)
cache_del_addr((struct sockaddr_in *)&client->destaddr);
}

static void on_connection_blocked(redsocks_client *client)
Expand Down Expand Up @@ -494,11 +495,13 @@ static int auto_retry(redsocks_client * client, int updcache)
if (updcache)
{
/* only add IP to cache when the IP is not in cache */
if (cache_get_addr_time(&client->destaddr) == NULL)
if (client->destaddr.ss_family == AF_INET
&& cache_get_addr_time((struct sockaddr_in *)&client->destaddr) == NULL)
{
cache_add_addr(&client->destaddr);
char destaddr_str[RED_INET_ADDRSTRLEN];
cache_add_addr((struct sockaddr_in *)&client->destaddr);
redsocks_log_error(client, LOG_DEBUG, "ADD IP to cache: %s",
inet_ntoa(client->destaddr.sin_addr));
red_inet_ntop(&client->destaddr, destaddr_str, sizeof(destaddr_str)));
}
}

Expand Down Expand Up @@ -616,8 +619,8 @@ static void auto_event_error(struct bufferevent *buffev, short what, void *_arg)
&& what == (BEV_EVENT_WRITING | BEV_EVENT_TIMEOUT))
{
// Update access time for IP fails again.
if (aclient->quick_check)
cache_touch_addr(&client->destaddr);
if (aclient->quick_check && client->destaddr.ss_family == AF_INET)
cache_touch_addr((struct sockaddr_in*)&client->destaddr);

on_connection_blocked(client);
/* In case timeout occurs while connecting relay, we try to connect
Expand Down Expand Up @@ -685,7 +688,8 @@ static int auto_connect_relay(redsocks_client *client)

if (aclient->state == AUTOPROXY_NEW)
{
acc_time = cache_get_addr_time(&client->destaddr);
if (client->destaddr.ss_family == AF_INET)
acc_time = cache_get_addr_time((struct sockaddr_in *)&client->destaddr);
if (acc_time)
{
redsocks_log_error(client, LOG_DEBUG, "Found dest IP in cache");
Expand All @@ -710,7 +714,7 @@ static int auto_connect_relay(redsocks_client *client)
/* connect to target directly without going through proxy */
client->relay = red_connect_relay(
config->interface,
(struct sockaddr *)&client->destaddr,
&client->destaddr,
NULL,
auto_relay_connected,
auto_event_error,
Expand Down
26 changes: 21 additions & 5 deletions base.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
typedef struct redirector_subsys_t {
int (*init)();
void (*fini)();
int (*getdestaddr)(int fd, const struct sockaddr_in *client, const struct sockaddr_in *bindaddr, struct sockaddr_in *destaddr);
int (*getdestaddr)(int fd, const struct sockaddr_storage *client, const struct sockaddr_storage *bindaddr, struct sockaddr_storage *destaddr);
const char *name;
// some subsystems may store data here:
int private;
Expand Down Expand Up @@ -124,7 +124,10 @@ static int redir_init_ipf()
return redir_open_private(fname, O_RDONLY);
}

static int getdestaddr_ipf(int fd, const struct sockaddr_in *client, const struct sockaddr_in *bindaddr, struct sockaddr_in *destaddr)
static int getdestaddr_ipf(int fd,
const struct sockaddr_storage *client,
const struct sockaddr_storage *bindaddr,
struct sockaddr_storage *destaddr)
{
int natfd = instance.redirector->private;
struct natlookup natLookup;
Expand Down Expand Up @@ -184,6 +187,7 @@ static int redir_init_pf()
return redir_open_private("/dev/pf", O_RDWR);
}

// FIXME: Support IPv6
static int getdestaddr_pf(
int fd, const struct sockaddr_in *client, const struct sockaddr_in *bindaddr,
struct sockaddr_in *destaddr)
Expand Down Expand Up @@ -233,7 +237,11 @@ static int getdestaddr_pf(
#endif

#ifdef USE_IPTABLES
static int getdestaddr_iptables(int fd, const struct sockaddr_in *client, const struct sockaddr_in *bindaddr, struct sockaddr_in *destaddr)
static int getdestaddr_iptables(
int fd,
const struct sockaddr_storage *client,
const struct sockaddr_storage *bindaddr,
struct sockaddr_storage *destaddr)
{
socklen_t socklen = sizeof(*destaddr);
int error;
Expand All @@ -247,7 +255,11 @@ static int getdestaddr_iptables(int fd, const struct sockaddr_in *client, const
}
#endif

static int getdestaddr_generic(int fd, const struct sockaddr_in *client, const struct sockaddr_in *bindaddr, struct sockaddr_in *destaddr)
static int getdestaddr_generic(
int fd,
const struct sockaddr_storage *client,
const struct sockaddr_storage *bindaddr,
struct sockaddr_storage *destaddr)
{
socklen_t socklen = sizeof(*destaddr);
int error;
Expand All @@ -260,7 +272,11 @@ static int getdestaddr_generic(int fd, const struct sockaddr_in *client, const s
return 0;
}

int getdestaddr(int fd, const struct sockaddr_in *client, const struct sockaddr_in *bindaddr, struct sockaddr_in *destaddr)
int getdestaddr(
int fd,
const struct sockaddr_storage *client,
const struct sockaddr_storage *bindaddr,
struct sockaddr_storage *destaddr)
{
return instance.redirector->getdestaddr(fd, client, bindaddr, destaddr);
}
Expand Down
2 changes: 1 addition & 1 deletion base.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef BASE_H_SUN_JUN__3_20_15_57_2007
#define BASE_H_SUN_JUN__3_20_15_57_2007

int getdestaddr(int fd, const struct sockaddr_in *client, const struct sockaddr_in *bindaddr, struct sockaddr_in *destaddr);
int getdestaddr(int fd, const struct sockaddr_storage *client, const struct sockaddr_storage *bindaddr, struct sockaddr_storage *destaddr);
int apply_tcp_keepalive(int fd);
int apply_reuseport(int fd);

Expand Down
2 changes: 1 addition & 1 deletion direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ static int direct_connect_relay(redsocks_client *client)
// Allowing binding relay socket to specified IP for outgoing connections
client->relay = red_connect_relay(
interface,
(struct sockaddr *)&client->destaddr,
&client->destaddr,
NULL,
redsocks_relay_connected,
redsocks_event_error,
Expand Down
19 changes: 7 additions & 12 deletions http-connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,17 +187,17 @@ struct evbuffer *httpc_mkconnect(redsocks_client *client)
const char *auth_scheme = NULL;
char *auth_string = NULL;

/* calculate uri */
char uri[RED_INET_ADDRSTRLEN];
red_inet_ntop(&client->destaddr, uri, sizeof(uri));

if (auth->last_auth_query != NULL) {
/* find previous auth challange */

if (strncasecmp(auth->last_auth_query, "Basic", 5) == 0) {
auth_string = basic_authentication_encode(client->instance->config.login, client->instance->config.password);
auth_scheme = "Basic";
} else if (strncasecmp(auth->last_auth_query, "Digest", 6) == 0) {
/* calculate uri */
char uri[128];
snprintf(uri, 128, "%s:%u", inet_ntoa(client->destaddr.sin_addr), ntohs(client->destaddr.sin_port));

/* prepare an random string for cnounce */
char cnounce[17];
snprintf(cnounce, sizeof(cnounce), "%08x%08x", red_randui32(), red_randui32());
Expand All @@ -210,16 +210,11 @@ struct evbuffer *httpc_mkconnect(redsocks_client *client)
}

if (auth_string == NULL) {
len = evbuffer_add_printf(buff,
"CONNECT %s:%u HTTP/1.0\r\n\r\n",
inet_ntoa(client->destaddr.sin_addr),
ntohs(client->destaddr.sin_port)
);
len = evbuffer_add_printf(buff, "CONNECT %s HTTP/1.0\r\n\r\n", uri);
} else {
len = evbuffer_add_printf(buff,
"CONNECT %s:%u HTTP/1.0\r\n%s %s %s\r\n\r\n",
inet_ntoa(client->destaddr.sin_addr),
ntohs(client->destaddr.sin_port),
"CONNECT %s HTTP/1.0\r\n%s %s %s\r\n\r\n",
uri,
auth_response_header,
auth_scheme,
auth_string
Expand Down
22 changes: 11 additions & 11 deletions http-relay.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,17 +382,17 @@ static int httpr_append_header(redsocks_client *client, char *line)
}

// This function is not reenterable
static char *fmt_http_host(struct sockaddr_in addr)
static const char *fmt_http_host(struct sockaddr_storage * addr)
{
static char host[] = "123.123.123.123:12345";
if (ntohs(addr.sin_port) == 80)
return inet_ntoa(addr.sin_addr);
static char host[RED_INET_ADDRSTRLEN];

if (
(addr->ss_family == AF_INET && ntohs(((struct sockaddr_in *)addr)->sin_port) == 80)
|| (addr->ss_family == AF_INET6 && ntohs(((struct sockaddr_in6 *)addr)->sin6_port) == 80)
)
return inet_ntop(addr->ss_family, addr, &host[0], sizeof(host));
else {
snprintf(host, sizeof(host),
"%s:%u",
inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port)
);
red_inet_ntop(addr, host, sizeof(host));
return host;
}
}
Expand All @@ -401,7 +401,7 @@ static int httpr_toss_http_firstline(redsocks_client *client)
{
httpr_client *httpr = (void*)(client + 1);
char *uri = NULL;
char *host = httpr->has_host ? httpr->host : fmt_http_host(client->destaddr);
const char *host = httpr->has_host ? httpr->host : fmt_http_host(&client->destaddr);
static char nbuff[MAX_HTTP_REQUEST_LINE_LENGTH + 1];
size_t len = 0;

Expand Down Expand Up @@ -525,7 +525,7 @@ static void httpr_client_read_cb(struct bufferevent *buffev, void *_arg)
if (!httpr->has_host) {
char host[32]; // "Host: 123.456.789.012:34567"
int written_wo_null = snprintf(host, sizeof(host), "Host: %s",
fmt_http_host(client->destaddr));
fmt_http_host(&client->destaddr));
UNUSED(written_wo_null);
assert(0 < written_wo_null && written_wo_null < sizeof(host));
if (httpr_append_header(client, host) < 0)
Expand Down
4 changes: 2 additions & 2 deletions ipcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ static int save_cache(const char * path)
item = get_cache_data(blk, idx);
if (item && item->present)
{
red_inet_ntop(&item->addr, addr_str, sizeof(addr_str));
red_inet_ntop((struct sockaddr_storage *)&item->addr, addr_str, sizeof(addr_str));
fprintf(f, "%s\n", addr_str);
}
}
Expand Down Expand Up @@ -419,7 +419,7 @@ static void cache_dumper()
if (item && item->present)
{
count++;
red_inet_ntop(&item->addr, addr_str[p], sizeof(addr_str[0]));
red_inet_ntop((struct sockaddr_storage *)&item->addr, addr_str[p], sizeof(addr_str[0]));
p++;
if (p == ADDR_COUNT_PER_LINE)
{
Expand Down
Loading

0 comments on commit ea2b56a

Please sign in to comment.