Przeglądaj źródła

redsocks: add new package

Redsocks is a daemon running on the local system, that will transparently
tunnel any TCP connection via a remote SOCKS4, SOCKS5 or HTTP proxy server. It
uses the system firewall's redirection facility to intercept TCP connections,
thus the redirection is system-wide, with fine-grained control, and does
not depend on LD_PRELOAD libraries.

Signed-off-by: Johannes Morgenroth <jm@m-network.de>
Johannes Morgenroth 10 lat temu
rodzic
commit
8c0260db9e

+ 56
- 0
net/redsocks/Makefile Wyświetl plik

@@ -0,0 +1,56 @@
1
+#
2
+# Copyright (C) 2014 OpenWrt.org
3
+#
4
+# This is free software, licensed under the GNU General Public License v2.
5
+# See /LICENSE for more information.
6
+#
7
+
8
+include $(TOPDIR)/rules.mk
9
+
10
+PKG_NAME:=redsocks
11
+PKG_VERSION:=0.4
12
+PKG_RELEASE:=1
13
+
14
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-release-$(PKG_VERSION)
15
+PKG_SOURCE:=release-$(PKG_VERSION).tar.gz
16
+PKG_SOURCE_URL:=https://github.com/darkk/redsocks/archive/
17
+PKG_MD5SUM:=810102ef06a9ea796f310ae811afc6a8
18
+PKG_MAINTAINER:=Johannes Morgenroth <jm@m-network.de>
19
+PKG_LICENSE:=Apache-2.0
20
+
21
+include $(INCLUDE_DIR)/package.mk
22
+
23
+define Package/redsocks
24
+  SECTION:=net
25
+  CATEGORY:=Network
26
+  DEPENDS:=+libevent2
27
+  TITLE:=Redirect any TCP connection to a SOCKS or HTTPS proxy server
28
+endef
29
+
30
+define Package/redsocks/conffiles
31
+/etc/redsocks.conf
32
+endef
33
+
34
+define Package/redsocks/description
35
+ Redsocks is a daemon running on the local system, that will transparently
36
+ tunnel any TCP connection via a remote SOCKS4, SOCKS5 or HTTP proxy server. It
37
+ uses the system firewall's redirection facility to intercept TCP connections,
38
+ thus the redirection is system-wide, with fine-grained control, and does
39
+ not depend on LD_PRELOAD libraries.
40
+ 
41
+ Redsocks supports tunneling TCP connections and UDP packets. It has
42
+ authentication support for both, SOCKS and HTTP proxies.
43
+ 
44
+ Also included is a small DNS server returning answers with the "truncated" flag
45
+ set for any UDP query, forcing the resolver to use TCP.
46
+endef
47
+
48
+define Package/redsocks/install
49
+	$(INSTALL_DIR) $(1)/usr/sbin/
50
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/redsocks $(1)/usr/sbin/
51
+	$(INSTALL_DIR) $(1)/etc/init.d/
52
+	$(INSTALL_BIN) files/redsocks.init $(1)/etc/init.d/redsocks
53
+	$(INSTALL_CONF) files/redsocks.conf $(1)/etc/
54
+endef
55
+
56
+$(eval $(call BuildPackage,redsocks))

+ 108
- 0
net/redsocks/files/redsocks.conf Wyświetl plik

@@ -0,0 +1,108 @@
1
+base {
2
+	// debug: connection progress & client list on SIGUSR1
3
+	log_debug = off;
4
+
5
+	// info: start and end of client session
6
+	log_info = on;
7
+
8
+	/* possible `log' values are:
9
+	 *   stderr
10
+	 *   "file:/path/to/file"
11
+	 *   syslog:FACILITY  facility is any of "daemon", "local0"..."local7"
12
+	 */
13
+	// log = stderr;
14
+	// log = "file:/path/to/file";
15
+	log = "syslog:local7";
16
+
17
+	// detach from console
18
+	daemon = on;
19
+
20
+	/* Change uid, gid and root directory, these options require root
21
+	 * privilegies on startup.
22
+	 * Note, your chroot may requre /etc/localtime if you write log to syslog.
23
+	 * Log is opened before chroot & uid changing.
24
+	 */
25
+	// user = nobody;
26
+	// group = nobody;
27
+	// chroot = "/var/chroot";
28
+
29
+	/* possible `redirector' values are:
30
+	 *   iptables   - for Linux
31
+	 *   ipf        - for FreeBSD
32
+	 *   pf         - for OpenBSD
33
+	 *   generic    - some generic redirector that MAY work
34
+	 */
35
+	redirector = iptables;
36
+}
37
+
38
+redsocks {
39
+	/* `local_ip' defaults to 127.0.0.1 for security reasons,
40
+	 * use 0.0.0.0 if you want to listen on every interface.
41
+	 * `local_*' are used as port to redirect to.
42
+	 */
43
+	local_ip = 127.0.0.1;
44
+	local_port = 12345;
45
+
46
+	// listen() queue length. Default value is SOMAXCONN and it should be
47
+	// good enough for most of us.
48
+	// listenq = 128; // SOMAXCONN equals 128 on my Linux box.
49
+
50
+	// `max_accept_backoff` is a delay to retry `accept()` after accept
51
+	// failure (e.g. due to lack of file descriptors). It's measured in
52
+	// milliseconds and maximal value is 65535. `min_accept_backoff` is
53
+	// used as initial backoff value and as a damper for `accept() after
54
+	// close()` logic.
55
+	// min_accept_backoff = 100;
56
+	// max_accept_backoff = 60000;
57
+
58
+	// `ip' and `port' are IP and tcp-port of proxy-server
59
+	// You can also use hostname instead of IP, only one (random)
60
+	// address of multihomed host will be used.
61
+	ip = example.org;
62
+	port = 1080;
63
+
64
+
65
+	// known types: socks4, socks5, http-connect, http-relay
66
+	type = socks5;
67
+
68
+	// login = "foobar";
69
+	// password = "baz";
70
+}
71
+
72
+redudp {
73
+	// `local_ip' should not be 0.0.0.0 as it's also used for outgoing
74
+	// packets that are sent as replies - and it should be fixed
75
+	// if we want NAT to work properly.
76
+	local_ip = 127.0.0.1;
77
+	local_port = 10053;
78
+
79
+	// `ip' and `port' of socks5 proxy server.
80
+	ip = 10.0.0.1;
81
+	port = 1080;
82
+	login = username;
83
+	password = pazzw0rd;
84
+
85
+	// redsocks knows about two options while redirecting UDP packets at
86
+	// linux: TPROXY and REDIRECT.  TPROXY requires more complex routing
87
+	// configuration and fresh kernel (>= 2.6.37 according to squid
88
+	// developers[1]) but has hack-free way to get original destination
89
+	// address, REDIRECT is easier to configure, but requires `dest_ip` and
90
+	// `dest_port` to be set, limiting packet redirection to single
91
+	// destination.
92
+	// [1] http://wiki.squid-cache.org/Features/Tproxy4
93
+	dest_ip = 8.8.8.8;
94
+	dest_port = 53;
95
+
96
+	udp_timeout = 30;
97
+	udp_timeout_stream = 180;
98
+}
99
+
100
+dnstc {
101
+	// fake and really dumb DNS server that returns "truncated answer" to
102
+	// every query via UDP, RFC-compliant resolver should repeat same query
103
+	// via TCP in this case.
104
+	local_ip = 127.0.0.1;
105
+	local_port = 5300;
106
+}
107
+
108
+// you can add more `redsocks' and `redudp' sections if you need.

+ 36
- 0
net/redsocks/files/redsocks.init Wyświetl plik

@@ -0,0 +1,36 @@
1
+#!/bin/sh /etc/rc.common
2
+# Copyright (C) 2007 OpenWrt.org
3
+
4
+START=90
5
+
6
+# check if configuration exists
7
+[ -e "/etc/redsocks.conf" ] || exit 0
8
+
9
+start() {
10
+	if [ -e "/var/run/redsocks.pid" ]; then
11
+		echo "redsocks is already running"
12
+		exit 0
13
+	fi
14
+
15
+	/bin/echo -n "running redsocks ..."
16
+	
17
+	# startup the safety-wrapper for the daemon
18
+	/usr/sbin/redsocks -p /var/run/redsocks.pid
19
+	
20
+	/bin/echo " done"
21
+}
22
+
23
+stop() {
24
+	if [ ! -e "/var/run/redsocks.pid" ]; then
25
+		echo "redsocks is not running"
26
+		exit 0
27
+	fi
28
+
29
+	/bin/echo -n "stopping redsocks ..."
30
+	
31
+	# kill the process
32
+	/bin/kill $(cat /var/run/redsocks.pid)
33
+	rm /var/run/redsocks.pid
34
+	
35
+	echo " done"
36
+}

+ 53
- 0
net/redsocks/patches/0001-Fix-bug-in-DNS-resolution-results-were-ignored-since.patch Wyświetl plik

@@ -0,0 +1,53 @@
1
+From 290f19972e9f7b74f818ae211cb535e32f1f314f Mon Sep 17 00:00:00 2001
2
+From: Leonid Evdokimov <leon@darkk.net.ru>
3
+Date: Tue, 10 Apr 2012 00:57:26 +0400
4
+Subject: [PATCH 01/12] Fix bug in DNS resolution - results were ignored (since
5
+ 8179a1ff).
6
+
7
+---
8
+ parser.c | 10 +++++-----
9
+ 1 file changed, 5 insertions(+), 5 deletions(-)
10
+
11
+diff --git a/parser.c b/parser.c
12
+index 85d3533..6198828 100644
13
+--- a/parser.c
14
++++ b/parser.c
15
+@@ -295,22 +295,22 @@ static int vp_in_addr(parser_context *context, void *addr, const char *token)
16
+ 		memcpy(addr, &ia, sizeof(ia));
17
+ 	}
18
+ 	else {
19
+-		struct addrinfo *addr, hints;
20
++		struct addrinfo *ainfo, hints;
21
+ 		int err;
22
+ 		memset(&hints, 0, sizeof(hints));
23
+ 		hints.ai_family = AF_INET; /* IPv4-only */
24
+ 		hints.ai_socktype = SOCK_STREAM; /* I want to have one address once and ONLY once, that's why I specify socktype and protocol */
25
+ 		hints.ai_protocol = IPPROTO_TCP;
26
+ 		hints.ai_flags = AI_ADDRCONFIG; /* I don't need IPv4 addrs without IPv4 connectivity */
27
+-		err = getaddrinfo(token, NULL, &hints, &addr);
28
++		err = getaddrinfo(token, NULL, &hints, &ainfo);
29
+ 		if (err == 0) {
30
+ 			int count, taken;
31
+ 			struct addrinfo *iter;
32
+ 			struct sockaddr_in *resolved_addr;
33
+-			for (iter = addr, count = 0; iter; iter = iter->ai_next, ++count)
34
++			for (iter = ainfo, count = 0; iter; iter = iter->ai_next, ++count)
35
+ 				;
36
+ 			taken = rand() % count;
37
+-			for (iter = addr; taken > 0; iter = iter->ai_next, --taken)
38
++			for (iter = ainfo; taken > 0; iter = iter->ai_next, --taken)
39
+ 				;
40
+ 			resolved_addr = (struct sockaddr_in*)iter->ai_addr;
41
+ 			assert(resolved_addr->sin_family == iter->ai_family && iter->ai_family == AF_INET);
42
+@@ -318,7 +318,7 @@ static int vp_in_addr(parser_context *context, void *addr, const char *token)
43
+ 				log_error(LOG_WARNING, "%s resolves to %d addresses, using %s",
44
+ 				          token, count, inet_ntoa(resolved_addr->sin_addr));
45
+ 			memcpy(addr, &resolved_addr->sin_addr, sizeof(ia));
46
+-			freeaddrinfo(addr);
47
++			freeaddrinfo(ainfo);
48
+ 		}
49
+ 		else {
50
+ 			if (err == EAI_SYSTEM)
51
+-- 
52
+1.9.1
53
+

+ 161
- 0
net/redsocks/patches/0002-inet_ntop-red_inet_ntop.patch Wyświetl plik

@@ -0,0 +1,161 @@
1
+From 6015b3a6f26e04dd5d78cd6c1320886fc9035612 Mon Sep 17 00:00:00 2001
2
+From: Leonid Evdokimov <leon@darkk.net.ru>
3
+Date: Tue, 10 Apr 2012 01:37:34 +0400
4
+Subject: [PATCH 02/12] inet_ntop -> red_inet_ntop
5
+
6
+---
7
+ redsocks.c | 13 ++++---------
8
+ redudp.c   | 19 +++++++++++--------
9
+ utils.c    | 37 +++++++++++++++++++++++++++++++++----
10
+ utils.h    |  7 +++++++
11
+ 4 files changed, 55 insertions(+), 21 deletions(-)
12
+
13
+diff --git a/redsocks.c b/redsocks.c
14
+index d085e10..ba5eab2 100644
15
+--- a/redsocks.c
16
++++ b/redsocks.c
17
+@@ -207,22 +207,17 @@ void redsocks_log_write_plain(
18
+ 	int saved_errno = errno;
19
+ 	struct evbuffer *fmt = evbuffer_new();
20
+ 	va_list ap;
21
+-	char clientaddr_str[INET6_ADDRSTRLEN], destaddr_str[INET6_ADDRSTRLEN];
22
++	char clientaddr_str[RED_INET_ADDRSTRLEN], destaddr_str[RED_INET_ADDRSTRLEN];
23
+ 
24
+ 	if (!fmt) {
25
+ 		log_errno(LOG_ERR, "evbuffer_new()");
26
+ 		// no return, as I have to call va_start/va_end
27
+ 	}
28
+ 
29
+-	if (!inet_ntop(clientaddr->sin_family, &clientaddr->sin_addr, clientaddr_str, sizeof(clientaddr_str)))
30
+-		strncpy(clientaddr_str, "???", sizeof(clientaddr_str));
31
+-	if (!inet_ntop(destaddr->sin_family, &destaddr->sin_addr, destaddr_str, sizeof(destaddr_str)))
32
+-		strncpy(destaddr_str, "???", sizeof(destaddr_str));
33
+-
34
+ 	if (fmt) {
35
+-		evbuffer_add_printf(fmt, "[%s:%i->%s:%i]: %s",
36
+-				clientaddr_str, ntohs(clientaddr->sin_port),
37
+-				destaddr_str, ntohs(destaddr->sin_port),
38
++		evbuffer_add_printf(fmt, "[%s->%s]: %s",
39
++				red_inet_ntop(clientaddr, clientaddr_str, sizeof(clientaddr_str)),
40
++				red_inet_ntop(destaddr, destaddr_str, sizeof(destaddr_str)),
41
+ 				orig_fmt);
42
+ 	}
43
+ 
44
+diff --git a/redudp.c b/redudp.c
45
+index 0a97852..9516a50 100644
46
+--- a/redudp.c
47
++++ b/redudp.c
48
+@@ -436,10 +436,9 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
49
+ 		return;
50
+ 
51
+ 	if (memcmp(&udprelayaddr, &client->udprelayaddr, sizeof(udprelayaddr)) != 0) {
52
+-		char buf[INET6_ADDRSTRLEN];
53
+-		const char *addr = inet_ntop(udprelayaddr.sin_family, &udprelayaddr.sin_addr, buf, sizeof(buf));
54
+-		redudp_log_error(client, LOG_NOTICE, "Got packet from unexpected address %s:%u.",
55
+-		                 addr ? addr : "?", ntohs(udprelayaddr.sin_port));
56
++		char buf[RED_INET_ADDRSTRLEN];
57
++		redudp_log_error(client, LOG_NOTICE, "Got packet from unexpected address %s.",
58
++		                 red_inet_ntop(&udprelayaddr, buf, sizeof(buf)));
59
+ 		return;
60
+ 	}
61
+ 
62
+@@ -459,10 +458,14 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
63
+ 	if (pkt.header.ip.port != client->instance->config.destaddr.sin_port ||
64
+ 	    pkt.header.ip.addr != client->instance->config.destaddr.sin_addr.s_addr)
65
+ 	{
66
+-		char buf[INET6_ADDRSTRLEN];
67
+-		const char *addr = inet_ntop(AF_INET, &pkt.header.ip.addr, buf, sizeof(buf));
68
+-		redudp_log_error(client, LOG_NOTICE, "Socks5 server relayed packet from unexpected address %s:%u.",
69
+-		                 addr ? addr : "?", ntohs(pkt.header.ip.port));
70
++		char buf[RED_INET_ADDRSTRLEN];
71
++		struct sockaddr_in pktaddr = {
72
++			.sin_family = AF_INET,
73
++			.sin_addr   = { pkt.header.ip.addr },
74
++			.sin_port   = pkt.header.ip.port,
75
++		};
76
++		redudp_log_error(client, LOG_NOTICE, "Socks5 server relayed packet from unexpected address %s.",
77
++		                 red_inet_ntop(&pktaddr, buf, sizeof(buf)));
78
+ 		return;
79
+ 	}
80
+ 
81
+diff --git a/utils.c b/utils.c
82
+index c6ced51..6e1f3af 100644
83
+--- a/utils.c
84
++++ b/utils.c
85
+@@ -18,6 +18,7 @@
86
+ #include <errno.h>
87
+ #include <assert.h>
88
+ #include <fcntl.h>
89
++#include <string.h>
90
+ #include <sys/socket.h>
91
+ #include <netinet/in.h>
92
+ #include <arpa/inet.h>
93
+@@ -42,10 +43,9 @@ int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *inadd
94
+ 	}
95
+ 
96
+ 	if (pktlen >= buflen) {
97
+-		char buf[INET6_ADDRSTRLEN];
98
+-		const char *addr = inet_ntop(inaddr->sin_family, &inaddr->sin_addr, buf, sizeof(buf));
99
+-		log_error(LOG_WARNING, "wow! Truncated udp packet of size %zd from %s:%u! impossible! dropping it...",
100
+-		          pktlen, addr ? addr : "?", ntohs(inaddr->sin_port));
101
++		char buf[RED_INET_ADDRSTRLEN];
102
++		log_error(LOG_WARNING, "wow! Truncated udp packet of size %zd from %s! impossible! dropping it...",
103
++		          pktlen, red_inet_ntop(inaddr, buf, sizeof(buf)));
104
+ 		return -1;
105
+ 	}
106
+ 
107
+@@ -176,4 +176,33 @@ int red_is_socket_connected_ok(struct bufferevent *buffev)
108
+ 	}
109
+ }
110
+ 
111
++char *red_inet_ntop(const struct sockaddr_in* sa, char* buffer, size_t buffer_size)
112
++{
113
++	const char *retval = 0;
114
++	size_t len = 0;
115
++	uint16_t port;
116
++	const char placeholder[] = "???:???";
117
++
118
++	assert(buffer_size >= sizeof(placeholder));
119
++
120
++	memset(buffer, buffer_size, 0);
121
++	if (sa->sin_family == AF_INET) {
122
++		retval = inet_ntop(AF_INET, &sa->sin_addr, buffer, buffer_size);
123
++		port = ((struct sockaddr_in*)sa)->sin_port;
124
++	}
125
++	else if (sa->sin_family == AF_INET6) {
126
++		retval = inet_ntop(AF_INET6, &((const struct sockaddr_in6*)sa)->sin6_addr, buffer, buffer_size);
127
++		port = ((struct sockaddr_in6*)sa)->sin6_port;
128
++	}
129
++	if (retval) {
130
++		assert(retval == buffer);
131
++		len = strlen(retval);
132
++		snprintf(buffer + len, buffer_size - len, ":%d", ntohs(port));
133
++	}
134
++	else {
135
++		strcpy(buffer, placeholder);
136
++	}
137
++	return buffer;
138
++}
139
++
140
+ /* vim:set tabstop=4 softtabstop=4 shiftwidth=4: */
141
+diff --git a/utils.h b/utils.h
142
+index f691b77..d3af00f 100644
143
+--- a/utils.h
144
++++ b/utils.h
145
+@@ -57,6 +57,13 @@ int fcntl_nonblock(int fd);
146
+ 				(what) & EVBUFFER_TIMEOUT ? "EVBUFFER_TIMEOUT" : "0", \
147
+ 				(what) & ~(EVBUFFER_READ|EVBUFFER_WRITE|EVBUFFER_EOF|EVBUFFER_ERROR|EVBUFFER_TIMEOUT)
148
+ 
149
++#if INET6_ADDRSTRLEN < INET_ADDRSTRLEN
150
++#	error Impossible happens: INET6_ADDRSTRLEN < INET_ADDRSTRLEN
151
++#else
152
++#	define RED_INET_ADDRSTRLEN (INET6_ADDRSTRLEN + 1 + 5 + 1) // addr + : + port + \0
153
++#endif
154
++char *red_inet_ntop(const struct sockaddr_in* sa, char* buffer, size_t buffer_size);
155
++
156
+ /* vim:set tabstop=4 softtabstop=4 shiftwidth=4: */
157
+ /* vim:set foldmethod=marker foldlevel=32 foldmarker={,}: */
158
+ #endif /* UTILS_H_SAT_FEB__2_02_24_05_2008 */
159
+-- 
160
+1.9.1
161
+

+ 449
- 0
net/redsocks/patches/0003-Initial-support-for-UDP-TPROXY-redirection.-No-more-.patch Wyświetl plik

@@ -0,0 +1,449 @@
1
+From 709646d59d96cb73a7e70347f37de9823e4e5f14 Mon Sep 17 00:00:00 2001
2
+From: Leonid Evdokimov <leon@darkk.net.ru>
3
+Date: Fri, 13 Apr 2012 01:57:23 +0400
4
+Subject: [PATCH 03/12] Initial support for UDP + TPROXY redirection. No more
5
+ dest_ip in redudp.
6
+
7
+ * TPROXY requires Linux 2.6.29+ (see man 7 ip[1]).
8
+ * all redsocks code is running as root to bind to arbitrary port.
9
+ * Non-Linux and old-Linux builds are broken at the moment.
10
+
11
+[1] http://www.kernel.org/doc/man-pages/online/pages/man7/ip.7.html
12
+---
13
+ dnstc.c  |   2 +-
14
+ redudp.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
15
+ redudp.h |   2 +
16
+ utils.c  |  43 +++++++++++++-
17
+ utils.h  |   2 +-
18
+ 5 files changed, 227 insertions(+), 19 deletions(-)
19
+
20
+diff --git a/dnstc.c b/dnstc.c
21
+index 43881d8..5f9fedd 100644
22
+--- a/dnstc.c
23
++++ b/dnstc.c
24
+@@ -68,7 +68,7 @@ static void dnstc_pkt_from_client(int fd, short what, void *_arg)
25
+ 	ssize_t pktlen, outgoing;
26
+ 
27
+ 	assert(fd == EVENT_FD(&self->listener));
28
+-	pktlen = red_recv_udp_pkt(fd, buf.raw, sizeof(buf), &clientaddr);
29
++	pktlen = red_recv_udp_pkt(fd, buf.raw, sizeof(buf), &clientaddr, NULL);
30
+ 	if (pktlen == -1)
31
+ 		return;
32
+ 
33
+diff --git a/redudp.c b/redudp.c
34
+index 9516a50..262af3e 100644
35
+--- a/redudp.c
36
++++ b/redudp.c
37
+@@ -15,6 +15,7 @@
38
+  */
39
+ 
40
+ #include <stdlib.h>
41
++#include <search.h>
42
+ #include <string.h>
43
+ #include <sys/types.h>
44
+ #include <sys/uio.h>
45
+@@ -33,30 +34,157 @@
46
+ #include "redudp.h"
47
+ 
48
+ #define redudp_log_error(client, prio, msg...) \
49
+-	redsocks_log_write_plain(__FILE__, __LINE__, __func__, 0, &(client)->clientaddr, &(client)->instance->config.destaddr, prio, ## msg)
50
++	redsocks_log_write_plain(__FILE__, __LINE__, __func__, 0, &(client)->clientaddr, get_destaddr(client), prio, ## msg)
51
+ #define redudp_log_errno(client, prio, msg...) \
52
+-	redsocks_log_write_plain(__FILE__, __LINE__, __func__, 1, &(client)->clientaddr, &(client)->instance->config.destaddr, prio, ## msg)
53
++	redsocks_log_write_plain(__FILE__, __LINE__, __func__, 1, &(client)->clientaddr, get_destaddr(client), prio, ## msg)
54
+ 
55
+ static void redudp_pkt_from_socks(int fd, short what, void *_arg);
56
+ static void redudp_drop_client(redudp_client *client);
57
+ static void redudp_fini_instance(redudp_instance *instance);
58
+ static int redudp_fini();
59
++static int redudp_transparent(int fd);
60
+ 
61
+ typedef struct redudp_expected_assoc_reply_t {
62
+ 	socks5_reply h;
63
+ 	socks5_addr_ipv4 ip;
64
+ } PACKED redudp_expected_assoc_reply;
65
+ 
66
++struct bound_udp4_key {
67
++	struct in_addr sin_addr;
68
++	uint16_t       sin_port;
69
++};
70
++
71
++struct bound_udp4 {
72
++	struct bound_udp4_key key;
73
++	int ref;
74
++	int fd;
75
++};
76
++
77
+ /***********************************************************************
78
+  * Helpers
79
+  */
80
++// TODO: separate binding to privileged process (this operation requires uid-0)
81
++static void* root_bound_udp4 = NULL; // to avoid two binds to same IP:port
82
++
83
++static int bound_udp4_cmp(const void *a, const void *b)
84
++{
85
++	return memcmp(a, b, sizeof(struct bound_udp4_key));
86
++}
87
++
88
++static void bound_udp4_mkkey(struct bound_udp4_key *key, const struct sockaddr_in *addr)
89
++{
90
++	memset(key, 0, sizeof(*key));
91
++	key->sin_addr = addr->sin_addr;
92
++	key->sin_port = addr->sin_port;
93
++}
94
++
95
++static int bound_udp4_get(const struct sockaddr_in *addr)
96
++{
97
++	struct bound_udp4_key key;
98
++	struct bound_udp4 *node, **pnode;
99
++
100
++	bound_udp4_mkkey(&key, addr);
101
++	// I assume, that memory allocation for lookup is awful, so I use
102
++	// tfind/tsearch pair instead of tsearch/check-result.
103
++	pnode = tfind(&key, &root_bound_udp4, bound_udp4_cmp);
104
++	if (pnode) {
105
++		assert((*pnode)->ref > 0);
106
++		(*pnode)->ref++;
107
++		return (*pnode)->fd;
108
++	}
109
++
110
++	node = calloc(1, sizeof(*node));
111
++	if (!node) {
112
++		log_errno(LOG_ERR, "calloc");
113
++		goto fail;
114
++	}
115
++
116
++	node->key = key;
117
++	node->ref = 1;
118
++	node->fd = socket(AF_INET, SOCK_DGRAM, 0);
119
++	if (node->fd == -1) {
120
++		log_errno(LOG_ERR, "socket");
121
++		goto fail;
122
++	}
123
++
124
++	if (0 != redudp_transparent(node->fd))
125
++		goto fail;
126
++
127
++	if (0 != bind(node->fd, (struct sockaddr*)addr, sizeof(*addr))) {
128
++		log_errno(LOG_ERR, "bind");
129
++		goto fail;
130
++	}
131
++
132
++	pnode = tsearch(node, &root_bound_udp4, bound_udp4_cmp);
133
++	if (!pnode) {
134
++		log_errno(LOG_ERR, "tsearch(%p) == %p", node, pnode);
135
++		goto fail;
136
++	}
137
++	assert(node == *pnode);
138
++
139
++	return node->fd;
140
++
141
++fail:
142
++	if (node) {
143
++		if (node->fd != -1)
144
++			redsocks_close(node->fd);
145
++		free(node);
146
++	}
147
++	return -1;
148
++}
149
++
150
++static void bound_udp4_put(const struct sockaddr_in *addr)
151
++{
152
++	struct bound_udp4_key key;
153
++	struct bound_udp4 **pnode, *node;
154
++	void *parent;
155
++
156
++	bound_udp4_mkkey(&key, addr);
157
++	pnode = tfind(&key, &root_bound_udp4, bound_udp4_cmp);
158
++	assert(pnode && (*pnode)->ref > 0);
159
++
160
++	node = *pnode;
161
++
162
++	node->ref--;
163
++	if (node->ref)
164
++		return;
165
++
166
++	parent = tdelete(node, &root_bound_udp4, bound_udp4_cmp);
167
++	assert(parent);
168
++
169
++	redsocks_close(node->fd); // expanding `pnode` to avoid use after free
170
++	free(node);
171
++}
172
++
173
++static int redudp_transparent(int fd)
174
++{
175
++	int on = 1;
176
++	int error = setsockopt(fd, SOL_IP, IP_TRANSPARENT, &on, sizeof(on));
177
++	if (error)
178
++		log_errno(LOG_ERR, "setsockopt(..., SOL_IP, IP_TRANSPARENT)");
179
++	return error;
180
++}
181
++
182
++static int do_tproxy(redudp_instance* instance)
183
++{
184
++	return instance->config.destaddr.sin_addr.s_addr == 0;
185
++}
186
++
187
++static struct sockaddr_in* get_destaddr(redudp_client *client)
188
++{
189
++	if (do_tproxy(client->instance))
190
++		return &client->destaddr;
191
++	else
192
++		return &client->instance->config.destaddr;
193
++}
194
++
195
+ static void redudp_fill_preamble(socks5_udp_preabmle *preamble, redudp_client *client)
196
+ {
197
+ 	preamble->reserved = 0;
198
+ 	preamble->frag_no = 0; /* fragmentation is not supported */
199
+ 	preamble->addrtype = socks5_addrtype_ipv4;
200
+-	preamble->ip.addr = client->instance->config.destaddr.sin_addr.s_addr;
201
+-	preamble->ip.port = client->instance->config.destaddr.sin_port;
202
++	preamble->ip.addr = get_destaddr(client)->sin_addr.s_addr;
203
++	preamble->ip.port = get_destaddr(client)->sin_port;
204
+ }
205
+ 
206
+ static struct evbuffer* socks5_mkmethods_plain_wrapper(void *p)
207
+@@ -104,6 +232,8 @@ static void redudp_drop_client(redudp_client *client)
208
+ 			redudp_log_errno(client, LOG_ERR, "event_del");
209
+ 		redsocks_close(fd);
210
+ 	}
211
++	if (client->sender_fd != -1)
212
++		bound_udp4_put(&client->destaddr);
213
+ 	list_for_each_entry_safe(q, tmp, &client->queue, list) {
214
+ 		list_del(&q->list);
215
+ 		free(q);
216
+@@ -344,7 +474,8 @@ static void redudp_relay_connected(struct bufferevent *buffev, void *_arg)
217
+ 	redudp_client *client = _arg;
218
+ 	int do_password = socks5_is_valid_cred(client->instance->config.login, client->instance->config.password);
219
+ 	int error;
220
+-	redudp_log_error(client, LOG_DEBUG, "<trace>");
221
++	char relayaddr_str[RED_INET_ADDRSTRLEN];
222
++	redudp_log_error(client, LOG_DEBUG, "via %s", red_inet_ntop(&client->instance->config.relayaddr, relayaddr_str, sizeof(relayaddr_str)));
223
+ 
224
+ 	if (!red_is_socket_connected_ok(buffev)) {
225
+ 		redudp_log_errno(client, LOG_NOTICE, "red_is_socket_connected_ok");
226
+@@ -382,7 +513,7 @@ static void redudp_timeout(int fd, short what, void *_arg)
227
+ 	redudp_drop_client(client);
228
+ }
229
+ 
230
+-static void redudp_first_pkt_from_client(redudp_instance *self, struct sockaddr_in *clientaddr, char *buf, size_t pktlen)
231
++static void redudp_first_pkt_from_client(redudp_instance *self, struct sockaddr_in *clientaddr, struct sockaddr_in *destaddr, char *buf, size_t pktlen)
232
+ {
233
+ 	redudp_client *client = calloc(1, sizeof(*client));
234
+ 
235
+@@ -395,9 +526,13 @@ static void redudp_first_pkt_from_client(redudp_instance *self, struct sockaddr_
236
+ 	INIT_LIST_HEAD(&client->queue);
237
+ 	client->instance = self;
238
+ 	memcpy(&client->clientaddr, clientaddr, sizeof(*clientaddr));
239
++	if (destaddr)
240
++		memcpy(&client->destaddr, destaddr, sizeof(client->destaddr));
241
+ 	evtimer_set(&client->timeout, redudp_timeout, client);
242
+ 	// XXX: self->relay_ss->init(client);
243
+ 
244
++	client->sender_fd = -1; // it's postponed until socks-server replies to avoid trivial DoS
245
++
246
+ 	client->relay = red_connect_relay(&client->instance->config.relayaddr,
247
+ 	                                  redudp_relay_connected, redudp_relay_error, client);
248
+ 	if (!client->relay)
249
+@@ -431,7 +566,7 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
250
+ 
251
+ 	assert(fd == EVENT_FD(&client->udprelay));
252
+ 
253
+-	pktlen = red_recv_udp_pkt(fd, pkt.buf, sizeof(pkt.buf), &udprelayaddr);
254
++	pktlen = red_recv_udp_pkt(fd, pkt.buf, sizeof(pkt.buf), &udprelayaddr, NULL);
255
+ 	if (pktlen == -1)
256
+ 		return;
257
+ 
258
+@@ -455,8 +590,8 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
259
+ 		return;
260
+ 	}
261
+ 
262
+-	if (pkt.header.ip.port != client->instance->config.destaddr.sin_port ||
263
+-	    pkt.header.ip.addr != client->instance->config.destaddr.sin_addr.s_addr)
264
++	if (pkt.header.ip.port != get_destaddr(client)->sin_port ||
265
++	    pkt.header.ip.addr != get_destaddr(client)->sin_addr.s_addr)
266
+ 	{
267
+ 		char buf[RED_INET_ADDRSTRLEN];
268
+ 		struct sockaddr_in pktaddr = {
269
+@@ -472,8 +607,18 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
270
+ 	redsocks_time(&client->last_relay_event);
271
+ 	redudp_bump_timeout(client);
272
+ 
273
++	if (do_tproxy(client->instance) && client->sender_fd == -1) {
274
++		client->sender_fd = bound_udp4_get(&client->destaddr);
275
++		if (client->sender_fd == -1) {
276
++			redudp_log_error(client, LOG_WARNING, "bound_udp4_get failure");
277
++			return;
278
++		}
279
++	}
280
++
281
+ 	fwdlen = pktlen - sizeof(pkt.header);
282
+-	outgoing = sendto(EVENT_FD(&client->instance->listener),
283
++	outgoing = sendto(do_tproxy(client->instance)
284
++	                      ? client->sender_fd
285
++	                      : EVENT_FD(&client->instance->listener),
286
+ 	                  pkt.buf + sizeof(pkt.header), fwdlen, 0,
287
+ 	                  (struct sockaddr*)&client->clientaddr, sizeof(client->clientaddr));
288
+ 	if (outgoing != fwdlen) {
289
+@@ -486,18 +631,21 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
290
+ static void redudp_pkt_from_client(int fd, short what, void *_arg)
291
+ {
292
+ 	redudp_instance *self = _arg;
293
+-	struct sockaddr_in clientaddr;
294
++	struct sockaddr_in clientaddr, destaddr, *pdestaddr;
295
+ 	char buf[0xFFFF]; // UDP packet can't be larger then that
296
+ 	ssize_t pktlen;
297
+ 	redudp_client *tmp, *client = NULL;
298
+ 
299
++	pdestaddr = do_tproxy(self) ? &destaddr : NULL;
300
++
301
+ 	assert(fd == EVENT_FD(&self->listener));
302
+-	pktlen = red_recv_udp_pkt(fd, buf, sizeof(buf), &clientaddr);
303
++	pktlen = red_recv_udp_pkt(fd, buf, sizeof(buf), &clientaddr, pdestaddr);
304
+ 	if (pktlen == -1)
305
+ 		return;
306
+ 
307
+ 	// TODO: this lookup may be SLOOOOOW.
308
+ 	list_for_each_entry(tmp, &self->clients, list) {
309
++		// TODO: check destaddr
310
+ 		if (0 == memcmp(&clientaddr, &tmp->clientaddr, sizeof(clientaddr))) {
311
+ 			client = tmp;
312
+ 			break;
313
+@@ -515,7 +663,7 @@ static void redudp_pkt_from_client(int fd, short what, void *_arg)
314
+ 		}
315
+ 	}
316
+ 	else {
317
+-		redudp_first_pkt_from_client(self, &clientaddr, buf, pktlen);
318
++		redudp_first_pkt_from_client(self, &clientaddr, pdestaddr, buf, pktlen);
319
+ 	}
320
+ }
321
+ 
322
+@@ -554,7 +702,6 @@ static int redudp_onenter(parser_section *section)
323
+ 	instance->config.relayaddr.sin_family = AF_INET;
324
+ 	instance->config.relayaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
325
+ 	instance->config.destaddr.sin_family = AF_INET;
326
+-	instance->config.destaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
327
+ 	instance->config.max_pktqueue = 5;
328
+ 	instance->config.udp_timeout = 30;
329
+ 	instance->config.udp_timeout_stream = 180;
330
+@@ -614,6 +761,28 @@ static int redudp_init_instance(redudp_instance *instance)
331
+ 		goto fail;
332
+ 	}
333
+ 
334
++	if (do_tproxy(instance)) {
335
++		int on = 1;
336
++		char buf[RED_INET_ADDRSTRLEN];
337
++		// iptables TPROXY target does not send packets to non-transparent sockets
338
++		if (0 != redudp_transparent(fd))
339
++			goto fail;
340
++
341
++		error = setsockopt(fd, SOL_IP, IP_RECVORIGDSTADDR, &on, sizeof(on));
342
++		if (error) {
343
++			log_errno(LOG_ERR, "setsockopt(listener, SOL_IP, IP_RECVORIGDSTADDR)");
344
++			goto fail;
345
++		}
346
++
347
++		log_error(LOG_DEBUG, "redudp @ %s: TPROXY", red_inet_ntop(&instance->config.bindaddr, buf, sizeof(buf)));
348
++	}
349
++	else {
350
++		char buf1[RED_INET_ADDRSTRLEN], buf2[RED_INET_ADDRSTRLEN];
351
++		log_error(LOG_DEBUG, "redudp @ %s: destaddr=%s",
352
++			red_inet_ntop(&instance->config.bindaddr, buf1, sizeof(buf1)),
353
++			red_inet_ntop(&instance->config.destaddr, buf2, sizeof(buf2)));
354
++	}
355
++
356
+ 	error = bind(fd, (struct sockaddr*)&instance->config.bindaddr, sizeof(instance->config.bindaddr));
357
+ 	if (error) {
358
+ 		log_errno(LOG_ERR, "bind");
359
+diff --git a/redudp.h b/redudp.h
360
+index 308bd33..3f1d9d1 100644
361
+--- a/redudp.h
362
++++ b/redudp.h
363
+@@ -24,6 +24,8 @@ typedef struct redudp_client_t {
364
+ 	list_head           list;
365
+ 	redudp_instance    *instance;
366
+ 	struct sockaddr_in  clientaddr;
367
++	struct sockaddr_in  destaddr;
368
++	int                 sender_fd; // shared between several clients socket (bound to `destaddr`)
369
+ 	struct event        timeout;
370
+ 	struct bufferevent *relay;
371
+ 	struct event        udprelay;
372
+diff --git a/utils.c b/utils.c
373
+index 6e1f3af..afdeea8 100644
374
+--- a/utils.c
375
++++ b/utils.c
376
+@@ -26,17 +26,54 @@
377
+ #include "utils.h"
378
+ #include "redsocks.h" // for redsocks_close
379
+ 
380
+-int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *inaddr)
381
++int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *inaddr, struct sockaddr_in *toaddr)
382
+ {
383
+ 	socklen_t addrlen = sizeof(*inaddr);
384
+ 	ssize_t pktlen;
385
+-
386
+-	pktlen = recvfrom(fd, buf, buflen, 0, (struct sockaddr*)inaddr, &addrlen);
387
++	struct msghdr msg;
388
++	struct iovec io;
389
++	char control[1024];
390
++
391
++	memset(&msg, 0, sizeof(msg));
392
++	msg.msg_name = inaddr;
393
++	msg.msg_namelen = sizeof(*inaddr);
394
++	msg.msg_iov = &io;
395
++	msg.msg_iovlen = 1;
396
++	msg.msg_control = control;
397
++	msg.msg_controllen = sizeof(control);
398
++	io.iov_base = buf;
399
++	io.iov_len = buflen;
400
++
401
++	pktlen = recvmsg(fd, &msg, 0);
402
+ 	if (pktlen == -1) {
403
+ 		log_errno(LOG_WARNING, "recvfrom");
404
+ 		return -1;
405
+ 	}
406
+ 
407
++	if (toaddr) {
408
++		memset(toaddr, 0, sizeof(*toaddr));
409
++		for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
410
++			if (
411
++				cmsg->cmsg_level == SOL_IP &&
412
++				cmsg->cmsg_type == IP_ORIGDSTADDR &&
413
++				cmsg->cmsg_len >= CMSG_LEN(sizeof(*toaddr))
414
++			) {
415
++				struct sockaddr_in* cmsgaddr = (struct sockaddr_in*)CMSG_DATA(cmsg);
416
++				char buf[RED_INET_ADDRSTRLEN];
417
++				log_error(LOG_DEBUG, "IP_ORIGDSTADDR: %s", red_inet_ntop(cmsgaddr, buf, sizeof(buf)));
418
++				memcpy(toaddr, cmsgaddr, sizeof(*toaddr));
419
++			}
420
++			else {
421
++				log_error(LOG_WARNING, "unexepcted cmsg (level,type) = (%d,%d)",
422
++					cmsg->cmsg_level, cmsg->cmsg_type);
423
++			}
424
++		}
425
++		if (toaddr->sin_family != AF_INET) {
426
++			log_error(LOG_WARNING, "(SOL_IP, IP_ORIGDSTADDR) not found");
427
++			return -1;
428
++		}
429
++	}
430
++
431
+ 	if (addrlen != sizeof(*inaddr)) {
432
+ 		log_error(LOG_WARNING, "unexpected address length %u instead of %zu", addrlen, sizeof(*inaddr));
433
+ 		return -1;
434
+diff --git a/utils.h b/utils.h
435
+index d3af00f..c2277e9 100644
436
+--- a/utils.h
437
++++ b/utils.h
438
+@@ -44,7 +44,7 @@ char *redsocks_evbuffer_readline(struct evbuffer *buf);
439
+ struct bufferevent* red_connect_relay(struct sockaddr_in *addr, evbuffercb writecb, everrorcb errorcb, void *cbarg);
440
+ int red_socket_geterrno(struct bufferevent *buffev);
441
+ int red_is_socket_connected_ok(struct bufferevent *buffev);
442
+-int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *inaddr);
443
++int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *fromaddr, struct sockaddr_in *toaddr);
444
+ 
445
+ int fcntl_nonblock(int fd);
446
+ 
447
+-- 
448
+1.9.1
449
+

+ 25
- 0
net/redsocks/patches/0004-Fix-transposition-of-memset-parameters.patch Wyświetl plik

@@ -0,0 +1,25 @@
1
+From b60b492602448b59aea194afd4991910d3613e5c Mon Sep 17 00:00:00 2001
2
+From: Cody Schafer <jmesmon@gmail.com>
3
+Date: Tue, 24 Apr 2012 04:33:13 -0500
4
+Subject: [PATCH 04/12] Fix transposition of memset parameters.
5
+
6
+---
7
+ utils.c | 2 +-
8
+ 1 file changed, 1 insertion(+), 1 deletion(-)
9
+
10
+diff --git a/utils.c b/utils.c
11
+index afdeea8..31c6894 100644
12
+--- a/utils.c
13
++++ b/utils.c
14
+@@ -222,7 +222,7 @@ char *red_inet_ntop(const struct sockaddr_in* sa, char* buffer, size_t buffer_si
15
+ 
16
+ 	assert(buffer_size >= sizeof(placeholder));
17
+ 
18
+-	memset(buffer, buffer_size, 0);
19
++	memset(buffer, 0, buffer_size);
20
+ 	if (sa->sin_family == AF_INET) {
21
+ 		retval = inet_ntop(AF_INET, &sa->sin_addr, buffer, buffer_size);
22
+ 		port = ((struct sockaddr_in*)sa)->sin_port;
23
+-- 
24
+1.9.1
25
+

+ 105
- 0
net/redsocks/patches/0005-Fix-compilation-on-Ubuntu-10.04-LTS-and-hopefully-De.patch Wyświetl plik

@@ -0,0 +1,105 @@
1
+From 18e2b5ed1ffb3e7c5dfec8ff41b3027163f680ed Mon Sep 17 00:00:00 2001
2
+From: Leonid Evdokimov <leon@darkk.net.ru>
3
+Date: Wed, 12 Sep 2012 02:05:39 +0400
4
+Subject: [PATCH 09/12] Fix compilation on Ubuntu 10.04 LTS and (hopefully)
5
+ Debian squeeze[1]
6
+
7
+fixes #28, fixes #22, fixes #24
8
+[1] current "stable" release
9
+---
10
+ libc-compat.h     | 25 +++++++++++++++++++++++++
11
+ libevent-compat.h | 11 +++++++++++
12
+ redsocks.c        |  1 +
13
+ redudp.c          |  1 +
14
+ utils.c           |  1 +
15
+ 5 files changed, 39 insertions(+)
16
+ create mode 100644 libc-compat.h
17
+ create mode 100644 libevent-compat.h
18
+
19
+diff --git a/libc-compat.h b/libc-compat.h
20
+new file mode 100644
21
+index 0000000..adcf63b
22
+--- /dev/null
23
++++ b/libc-compat.h
24
+@@ -0,0 +1,25 @@
25
++#ifndef UUID_67C91670_FCCB_4855_BDF7_609F1EECB8B4
26
++#define UUID_67C91670_FCCB_4855_BDF7_609F1EECB8B4
27
++
28
++/* all these definitions, are included into bits/in.h from libc6-dev 2.15-0ubuntu10
29
++ * from Ubuntu 12.04 and is not included into libc6-dev 2.11.1-0ubuntu7.10 from
30
++ * Ubuntu 10.04.
31
++ * linux/in.h is not included directly because of lots of redefinitions,
32
++ * extracting single value from linux/in.h is not done because it looks like
33
++ * autotools reinvention */
34
++#ifndef IP_ORIGDSTADDR
35
++#   warning Using hardcoded value for IP_ORIGDSTADDR as libc headers do not define it.
36
++#   define IP_ORIGDSTADDR 20
37
++#endif
38
++
39
++#ifndef IP_RECVORIGDSTADDR
40
++#   warning Using hardcoded value for IP_RECVORIGDSTADDR as libc headers do not define it.
41
++#   define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
42
++#endif
43
++
44
++#ifndef IP_TRANSPARENT
45
++#   warning Using hardcoded value for IP_TRANSPARENT as libc headers do not define it.
46
++#   define IP_TRANSPARENT 19
47
++#endif
48
++
49
++#endif // 67C91670_FCCB_4855_BDF7_609F1EECB8B4
50
+diff --git a/libevent-compat.h b/libevent-compat.h
51
+new file mode 100644
52
+index 0000000..a7f1ca1
53
+--- /dev/null
54
++++ b/libevent-compat.h
55
+@@ -0,0 +1,11 @@
56
++#ifndef UUID_FC148CFA_5ECC_488E_8A62_CD39406C9F1E
57
++#define UUID_FC148CFA_5ECC_488E_8A62_CD39406C9F1E
58
++
59
++/* evutil_socket_t is macros in libevent-2.0, not typedef, libevent-1.4 is
60
++ * still supported because of Ubuntu 10.04 LTS */
61
++#ifndef evutil_socket_t
62
++#   warning Using hardcoded value for evutil_socket_t as libevent headers do not define it.
63
++#   define evutil_socket_t int
64
++#endif
65
++
66
++#endif // FC148CFA_5ECC_488E_8A62_CD39406C9F1E
67
+diff --git a/redsocks.c b/redsocks.c
68
+index ba5eab2..878576f 100644
69
+--- a/redsocks.c
70
++++ b/redsocks.c
71
+@@ -33,6 +33,7 @@
72
+ #include "base.h"
73
+ #include "redsocks.h"
74
+ #include "utils.h"
75
++#include "libevent-compat.h"
76
+ 
77
+ 
78
+ #define REDSOCKS_RELAY_HALFBUFF  4096
79
+diff --git a/redudp.c b/redudp.c
80
+index 262af3e..05460dc 100644
81
+--- a/redudp.c
82
++++ b/redudp.c
83
+@@ -32,6 +32,7 @@
84
+ #include "main.h"
85
+ #include "redsocks.h"
86
+ #include "redudp.h"
87
++#include "libc-compat.h"
88
+ 
89
+ #define redudp_log_error(client, prio, msg...) \
90
+ 	redsocks_log_write_plain(__FILE__, __LINE__, __func__, 0, &(client)->clientaddr, get_destaddr(client), prio, ## msg)
91
+diff --git a/utils.c b/utils.c
92
+index 31c6894..7de3969 100644
93
+--- a/utils.c
94
++++ b/utils.c
95
+@@ -25,6 +25,7 @@
96
+ #include "log.h"
97
+ #include "utils.h"
98
+ #include "redsocks.h" // for redsocks_close
99
++#include "libc-compat.h"
100
+ 
101
+ int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *inaddr, struct sockaddr_in *toaddr)
102
+ {
103
+-- 
104
+1.9.1
105
+

+ 17
- 0
net/redsocks/patches/0006-fix_default_config_location.patch Wyświetl plik

@@ -0,0 +1,17 @@
1
+Description: change the default config file location
2
+ redsocks by default looks for ./redsocks.conf. Change this to
3
+ /etc/redsocks.conf for a more deterministic behaviour.
4
+Author: Apollon Oikonomopoulos <apoikos@gmail.com>
5
+Forwared: no
6
+Last-Update: 2013-04-23
7
+--- a/main.c
8
++++ b/main.c
9
+@@ -39,7 +39,7 @@
10
+ 	&dnstc_subsys,
11
+ };
12
+ 
13
+-static const char *confname = "redsocks.conf";
14
++static const char *confname = "/etc/redsocks.conf";
15
+ static const char *pidfile = NULL;
16
+ 
17
+ static void terminate(int sig, short what, void *_arg)