redsocks: updates to latest source and gcc build options
authorTed Hess <redacted>
Sat, 14 Nov 2015 15:54:24 +0000 (10:54 -0500)
committerTed Hess <redacted>
Sat, 14 Nov 2015 16:22:18 +0000 (11:22 -0500)
Signed-off-by: Ted Hess <redacted>
net/redsocks/Makefile
net/redsocks/patches/0001-Fix-bug-in-DNS-resolution-results-were-ignored-since.patch [deleted file]
net/redsocks/patches/0002-inet_ntop-red_inet_ntop.patch [deleted file]
net/redsocks/patches/0003-Initial-support-for-UDP-TPROXY-redirection.-No-more-.patch [deleted file]
net/redsocks/patches/0004-Fix-transposition-of-memset-parameters.patch [deleted file]
net/redsocks/patches/0005-Fix-compilation-on-Ubuntu-10.04-LTS-and-hopefully-De.patch [deleted file]
net/redsocks/patches/0006-fix_default_config_location.patch

index caf541e1bae7a7ad52648c833664b3138266ae51..4f5f563cae81c4a07151c57b1e8345ee2c29c7dd 100644 (file)
@@ -8,14 +8,14 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=redsocks
-PKG_VERSION:=0.4
+PKG_VERSION:=0.4-20150907
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
 PKG_SOURCE_URL:=https://github.com/darkk/redsocks.git
-PKG_SOURCE_VERSION:=release-0.4
+PKG_SOURCE_VERSION:=2118c616b4970a0436eceaa57a6e3451ec98ad2b
 
 PKG_MAINTAINER:=Johannes Morgenroth <jm@m-network.de>
 PKG_LICENSE:=Apache-2.0
diff --git a/net/redsocks/patches/0001-Fix-bug-in-DNS-resolution-results-were-ignored-since.patch b/net/redsocks/patches/0001-Fix-bug-in-DNS-resolution-results-were-ignored-since.patch
deleted file mode 100644 (file)
index 595be19..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-From 290f19972e9f7b74f818ae211cb535e32f1f314f Mon Sep 17 00:00:00 2001
-From: Leonid Evdokimov <leon@darkk.net.ru>
-Date: Tue, 10 Apr 2012 00:57:26 +0400
-Subject: [PATCH 01/12] Fix bug in DNS resolution - results were ignored (since
- 8179a1ff).
-
----
- parser.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/parser.c b/parser.c
-index 85d3533..6198828 100644
---- a/parser.c
-+++ b/parser.c
-@@ -295,22 +295,22 @@ static int vp_in_addr(parser_context *context, void *addr, const char *token)
-               memcpy(addr, &ia, sizeof(ia));
-       }
-       else {
--              struct addrinfo *addr, hints;
-+              struct addrinfo *ainfo, hints;
-               int err;
-               memset(&hints, 0, sizeof(hints));
-               hints.ai_family = AF_INET; /* IPv4-only */
-               hints.ai_socktype = SOCK_STREAM; /* I want to have one address once and ONLY once, that's why I specify socktype and protocol */
-               hints.ai_protocol = IPPROTO_TCP;
-               hints.ai_flags = AI_ADDRCONFIG; /* I don't need IPv4 addrs without IPv4 connectivity */
--              err = getaddrinfo(token, NULL, &hints, &addr);
-+              err = getaddrinfo(token, NULL, &hints, &ainfo);
-               if (err == 0) {
-                       int count, taken;
-                       struct addrinfo *iter;
-                       struct sockaddr_in *resolved_addr;
--                      for (iter = addr, count = 0; iter; iter = iter->ai_next, ++count)
-+                      for (iter = ainfo, count = 0; iter; iter = iter->ai_next, ++count)
-                               ;
-                       taken = rand() % count;
--                      for (iter = addr; taken > 0; iter = iter->ai_next, --taken)
-+                      for (iter = ainfo; taken > 0; iter = iter->ai_next, --taken)
-                               ;
-                       resolved_addr = (struct sockaddr_in*)iter->ai_addr;
-                       assert(resolved_addr->sin_family == iter->ai_family && iter->ai_family == AF_INET);
-@@ -318,7 +318,7 @@ static int vp_in_addr(parser_context *context, void *addr, const char *token)
-                               log_error(LOG_WARNING, "%s resolves to %d addresses, using %s",
-                                         token, count, inet_ntoa(resolved_addr->sin_addr));
-                       memcpy(addr, &resolved_addr->sin_addr, sizeof(ia));
--                      freeaddrinfo(addr);
-+                      freeaddrinfo(ainfo);
-               }
-               else {
-                       if (err == EAI_SYSTEM)
--- 
-1.9.1
-
diff --git a/net/redsocks/patches/0002-inet_ntop-red_inet_ntop.patch b/net/redsocks/patches/0002-inet_ntop-red_inet_ntop.patch
deleted file mode 100644 (file)
index 058556e..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-From 6015b3a6f26e04dd5d78cd6c1320886fc9035612 Mon Sep 17 00:00:00 2001
-From: Leonid Evdokimov <leon@darkk.net.ru>
-Date: Tue, 10 Apr 2012 01:37:34 +0400
-Subject: [PATCH 02/12] inet_ntop -> red_inet_ntop
-
----
- redsocks.c | 13 ++++---------
- redudp.c   | 19 +++++++++++--------
- utils.c    | 37 +++++++++++++++++++++++++++++++++----
- utils.h    |  7 +++++++
- 4 files changed, 55 insertions(+), 21 deletions(-)
-
-diff --git a/redsocks.c b/redsocks.c
-index d085e10..ba5eab2 100644
---- a/redsocks.c
-+++ b/redsocks.c
-@@ -207,22 +207,17 @@ void redsocks_log_write_plain(
-       int saved_errno = errno;
-       struct evbuffer *fmt = evbuffer_new();
-       va_list ap;
--      char clientaddr_str[INET6_ADDRSTRLEN], destaddr_str[INET6_ADDRSTRLEN];
-+      char clientaddr_str[RED_INET_ADDRSTRLEN], destaddr_str[RED_INET_ADDRSTRLEN];
-       if (!fmt) {
-               log_errno(LOG_ERR, "evbuffer_new()");
-               // no return, as I have to call va_start/va_end
-       }
--      if (!inet_ntop(clientaddr->sin_family, &clientaddr->sin_addr, clientaddr_str, sizeof(clientaddr_str)))
--              strncpy(clientaddr_str, "???", sizeof(clientaddr_str));
--      if (!inet_ntop(destaddr->sin_family, &destaddr->sin_addr, destaddr_str, sizeof(destaddr_str)))
--              strncpy(destaddr_str, "???", sizeof(destaddr_str));
--
-       if (fmt) {
--              evbuffer_add_printf(fmt, "[%s:%i->%s:%i]: %s",
--                              clientaddr_str, ntohs(clientaddr->sin_port),
--                              destaddr_str, ntohs(destaddr->sin_port),
-+              evbuffer_add_printf(fmt, "[%s->%s]: %s",
-+                              red_inet_ntop(clientaddr, clientaddr_str, sizeof(clientaddr_str)),
-+                              red_inet_ntop(destaddr, destaddr_str, sizeof(destaddr_str)),
-                               orig_fmt);
-       }
-diff --git a/redudp.c b/redudp.c
-index 0a97852..9516a50 100644
---- a/redudp.c
-+++ b/redudp.c
-@@ -436,10 +436,9 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
-               return;
-       if (memcmp(&udprelayaddr, &client->udprelayaddr, sizeof(udprelayaddr)) != 0) {
--              char buf[INET6_ADDRSTRLEN];
--              const char *addr = inet_ntop(udprelayaddr.sin_family, &udprelayaddr.sin_addr, buf, sizeof(buf));
--              redudp_log_error(client, LOG_NOTICE, "Got packet from unexpected address %s:%u.",
--                               addr ? addr : "?", ntohs(udprelayaddr.sin_port));
-+              char buf[RED_INET_ADDRSTRLEN];
-+              redudp_log_error(client, LOG_NOTICE, "Got packet from unexpected address %s.",
-+                               red_inet_ntop(&udprelayaddr, buf, sizeof(buf)));
-               return;
-       }
-@@ -459,10 +458,14 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
-       if (pkt.header.ip.port != client->instance->config.destaddr.sin_port ||
-           pkt.header.ip.addr != client->instance->config.destaddr.sin_addr.s_addr)
-       {
--              char buf[INET6_ADDRSTRLEN];
--              const char *addr = inet_ntop(AF_INET, &pkt.header.ip.addr, buf, sizeof(buf));
--              redudp_log_error(client, LOG_NOTICE, "Socks5 server relayed packet from unexpected address %s:%u.",
--                               addr ? addr : "?", ntohs(pkt.header.ip.port));
-+              char buf[RED_INET_ADDRSTRLEN];
-+              struct sockaddr_in pktaddr = {
-+                      .sin_family = AF_INET,
-+                      .sin_addr   = { pkt.header.ip.addr },
-+                      .sin_port   = pkt.header.ip.port,
-+              };
-+              redudp_log_error(client, LOG_NOTICE, "Socks5 server relayed packet from unexpected address %s.",
-+                               red_inet_ntop(&pktaddr, buf, sizeof(buf)));
-               return;
-       }
-diff --git a/utils.c b/utils.c
-index c6ced51..6e1f3af 100644
---- a/utils.c
-+++ b/utils.c
-@@ -18,6 +18,7 @@
- #include <errno.h>
- #include <assert.h>
- #include <fcntl.h>
-+#include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-@@ -42,10 +43,9 @@ int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *inadd
-       }
-       if (pktlen >= buflen) {
--              char buf[INET6_ADDRSTRLEN];
--              const char *addr = inet_ntop(inaddr->sin_family, &inaddr->sin_addr, buf, sizeof(buf));
--              log_error(LOG_WARNING, "wow! Truncated udp packet of size %zd from %s:%u! impossible! dropping it...",
--                        pktlen, addr ? addr : "?", ntohs(inaddr->sin_port));
-+              char buf[RED_INET_ADDRSTRLEN];
-+              log_error(LOG_WARNING, "wow! Truncated udp packet of size %zd from %s! impossible! dropping it...",
-+                        pktlen, red_inet_ntop(inaddr, buf, sizeof(buf)));
-               return -1;
-       }
-@@ -176,4 +176,33 @@ int red_is_socket_connected_ok(struct bufferevent *buffev)
-       }
- }
-+char *red_inet_ntop(const struct sockaddr_in* sa, char* buffer, size_t buffer_size)
-+{
-+      const char *retval = 0;
-+      size_t len = 0;
-+      uint16_t port;
-+      const char placeholder[] = "???:???";
-+
-+      assert(buffer_size >= sizeof(placeholder));
-+
-+      memset(buffer, buffer_size, 0);
-+      if (sa->sin_family == AF_INET) {
-+              retval = inet_ntop(AF_INET, &sa->sin_addr, buffer, buffer_size);
-+              port = ((struct sockaddr_in*)sa)->sin_port;
-+      }
-+      else if (sa->sin_family == AF_INET6) {
-+              retval = inet_ntop(AF_INET6, &((const struct sockaddr_in6*)sa)->sin6_addr, buffer, buffer_size);
-+              port = ((struct sockaddr_in6*)sa)->sin6_port;
-+      }
-+      if (retval) {
-+              assert(retval == buffer);
-+              len = strlen(retval);
-+              snprintf(buffer + len, buffer_size - len, ":%d", ntohs(port));
-+      }
-+      else {
-+              strcpy(buffer, placeholder);
-+      }
-+      return buffer;
-+}
-+
- /* vim:set tabstop=4 softtabstop=4 shiftwidth=4: */
-diff --git a/utils.h b/utils.h
-index f691b77..d3af00f 100644
---- a/utils.h
-+++ b/utils.h
-@@ -57,6 +57,13 @@ int fcntl_nonblock(int fd);
-                               (what) & EVBUFFER_TIMEOUT ? "EVBUFFER_TIMEOUT" : "0", \
-                               (what) & ~(EVBUFFER_READ|EVBUFFER_WRITE|EVBUFFER_EOF|EVBUFFER_ERROR|EVBUFFER_TIMEOUT)
-+#if INET6_ADDRSTRLEN < INET_ADDRSTRLEN
-+#     error Impossible happens: INET6_ADDRSTRLEN < INET_ADDRSTRLEN
-+#else
-+#     define RED_INET_ADDRSTRLEN (INET6_ADDRSTRLEN + 1 + 5 + 1) // addr + : + port + \0
-+#endif
-+char *red_inet_ntop(const struct sockaddr_in* sa, char* buffer, size_t buffer_size);
-+
- /* vim:set tabstop=4 softtabstop=4 shiftwidth=4: */
- /* vim:set foldmethod=marker foldlevel=32 foldmarker={,}: */
- #endif /* UTILS_H_SAT_FEB__2_02_24_05_2008 */
--- 
-1.9.1
-
diff --git a/net/redsocks/patches/0003-Initial-support-for-UDP-TPROXY-redirection.-No-more-.patch b/net/redsocks/patches/0003-Initial-support-for-UDP-TPROXY-redirection.-No-more-.patch
deleted file mode 100644 (file)
index b89f4be..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-From 709646d59d96cb73a7e70347f37de9823e4e5f14 Mon Sep 17 00:00:00 2001
-From: Leonid Evdokimov <leon@darkk.net.ru>
-Date: Fri, 13 Apr 2012 01:57:23 +0400
-Subject: [PATCH 03/12] Initial support for UDP + TPROXY redirection. No more
- dest_ip in redudp.
-
- * TPROXY requires Linux 2.6.29+ (see man 7 ip[1]).
- * all redsocks code is running as root to bind to arbitrary port.
- * Non-Linux and old-Linux builds are broken at the moment.
-
-[1] http://www.kernel.org/doc/man-pages/online/pages/man7/ip.7.html
----
- dnstc.c  |   2 +-
- redudp.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
- redudp.h |   2 +
- utils.c  |  43 +++++++++++++-
- utils.h  |   2 +-
- 5 files changed, 227 insertions(+), 19 deletions(-)
-
-diff --git a/dnstc.c b/dnstc.c
-index 43881d8..5f9fedd 100644
---- a/dnstc.c
-+++ b/dnstc.c
-@@ -68,7 +68,7 @@ static void dnstc_pkt_from_client(int fd, short what, void *_arg)
-       ssize_t pktlen, outgoing;
-       assert(fd == EVENT_FD(&self->listener));
--      pktlen = red_recv_udp_pkt(fd, buf.raw, sizeof(buf), &clientaddr);
-+      pktlen = red_recv_udp_pkt(fd, buf.raw, sizeof(buf), &clientaddr, NULL);
-       if (pktlen == -1)
-               return;
-diff --git a/redudp.c b/redudp.c
-index 9516a50..262af3e 100644
---- a/redudp.c
-+++ b/redudp.c
-@@ -15,6 +15,7 @@
-  */
- #include <stdlib.h>
-+#include <search.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/uio.h>
-@@ -33,30 +34,157 @@
- #include "redudp.h"
- #define redudp_log_error(client, prio, msg...) \
--      redsocks_log_write_plain(__FILE__, __LINE__, __func__, 0, &(client)->clientaddr, &(client)->instance->config.destaddr, prio, ## msg)
-+      redsocks_log_write_plain(__FILE__, __LINE__, __func__, 0, &(client)->clientaddr, get_destaddr(client), prio, ## msg)
- #define redudp_log_errno(client, prio, msg...) \
--      redsocks_log_write_plain(__FILE__, __LINE__, __func__, 1, &(client)->clientaddr, &(client)->instance->config.destaddr, prio, ## msg)
-+      redsocks_log_write_plain(__FILE__, __LINE__, __func__, 1, &(client)->clientaddr, get_destaddr(client), prio, ## msg)
- static void redudp_pkt_from_socks(int fd, short what, void *_arg);
- static void redudp_drop_client(redudp_client *client);
- static void redudp_fini_instance(redudp_instance *instance);
- static int redudp_fini();
-+static int redudp_transparent(int fd);
- typedef struct redudp_expected_assoc_reply_t {
-       socks5_reply h;
-       socks5_addr_ipv4 ip;
- } PACKED redudp_expected_assoc_reply;
-+struct bound_udp4_key {
-+      struct in_addr sin_addr;
-+      uint16_t       sin_port;
-+};
-+
-+struct bound_udp4 {
-+      struct bound_udp4_key key;
-+      int ref;
-+      int fd;
-+};
-+
- /***********************************************************************
-  * Helpers
-  */
-+// TODO: separate binding to privileged process (this operation requires uid-0)
-+static void* root_bound_udp4 = NULL; // to avoid two binds to same IP:port
-+
-+static int bound_udp4_cmp(const void *a, const void *b)
-+{
-+      return memcmp(a, b, sizeof(struct bound_udp4_key));
-+}
-+
-+static void bound_udp4_mkkey(struct bound_udp4_key *key, const struct sockaddr_in *addr)
-+{
-+      memset(key, 0, sizeof(*key));
-+      key->sin_addr = addr->sin_addr;
-+      key->sin_port = addr->sin_port;
-+}
-+
-+static int bound_udp4_get(const struct sockaddr_in *addr)
-+{
-+      struct bound_udp4_key key;
-+      struct bound_udp4 *node, **pnode;
-+
-+      bound_udp4_mkkey(&key, addr);
-+      // I assume, that memory allocation for lookup is awful, so I use
-+      // tfind/tsearch pair instead of tsearch/check-result.
-+      pnode = tfind(&key, &root_bound_udp4, bound_udp4_cmp);
-+      if (pnode) {
-+              assert((*pnode)->ref > 0);
-+              (*pnode)->ref++;
-+              return (*pnode)->fd;
-+      }
-+
-+      node = calloc(1, sizeof(*node));
-+      if (!node) {
-+              log_errno(LOG_ERR, "calloc");
-+              goto fail;
-+      }
-+
-+      node->key = key;
-+      node->ref = 1;
-+      node->fd = socket(AF_INET, SOCK_DGRAM, 0);
-+      if (node->fd == -1) {
-+              log_errno(LOG_ERR, "socket");
-+              goto fail;
-+      }
-+
-+      if (0 != redudp_transparent(node->fd))
-+              goto fail;
-+
-+      if (0 != bind(node->fd, (struct sockaddr*)addr, sizeof(*addr))) {
-+              log_errno(LOG_ERR, "bind");
-+              goto fail;
-+      }
-+
-+      pnode = tsearch(node, &root_bound_udp4, bound_udp4_cmp);
-+      if (!pnode) {
-+              log_errno(LOG_ERR, "tsearch(%p) == %p", node, pnode);
-+              goto fail;
-+      }
-+      assert(node == *pnode);
-+
-+      return node->fd;
-+
-+fail:
-+      if (node) {
-+              if (node->fd != -1)
-+                      redsocks_close(node->fd);
-+              free(node);
-+      }
-+      return -1;
-+}
-+
-+static void bound_udp4_put(const struct sockaddr_in *addr)
-+{
-+      struct bound_udp4_key key;
-+      struct bound_udp4 **pnode, *node;
-+      void *parent;
-+
-+      bound_udp4_mkkey(&key, addr);
-+      pnode = tfind(&key, &root_bound_udp4, bound_udp4_cmp);
-+      assert(pnode && (*pnode)->ref > 0);
-+
-+      node = *pnode;
-+
-+      node->ref--;
-+      if (node->ref)
-+              return;
-+
-+      parent = tdelete(node, &root_bound_udp4, bound_udp4_cmp);
-+      assert(parent);
-+
-+      redsocks_close(node->fd); // expanding `pnode` to avoid use after free
-+      free(node);
-+}
-+
-+static int redudp_transparent(int fd)
-+{
-+      int on = 1;
-+      int error = setsockopt(fd, SOL_IP, IP_TRANSPARENT, &on, sizeof(on));
-+      if (error)
-+              log_errno(LOG_ERR, "setsockopt(..., SOL_IP, IP_TRANSPARENT)");
-+      return error;
-+}
-+
-+static int do_tproxy(redudp_instance* instance)
-+{
-+      return instance->config.destaddr.sin_addr.s_addr == 0;
-+}
-+
-+static struct sockaddr_in* get_destaddr(redudp_client *client)
-+{
-+      if (do_tproxy(client->instance))
-+              return &client->destaddr;
-+      else
-+              return &client->instance->config.destaddr;
-+}
-+
- static void redudp_fill_preamble(socks5_udp_preabmle *preamble, redudp_client *client)
- {
-       preamble->reserved = 0;
-       preamble->frag_no = 0; /* fragmentation is not supported */
-       preamble->addrtype = socks5_addrtype_ipv4;
--      preamble->ip.addr = client->instance->config.destaddr.sin_addr.s_addr;
--      preamble->ip.port = client->instance->config.destaddr.sin_port;
-+      preamble->ip.addr = get_destaddr(client)->sin_addr.s_addr;
-+      preamble->ip.port = get_destaddr(client)->sin_port;
- }
- static struct evbuffer* socks5_mkmethods_plain_wrapper(void *p)
-@@ -104,6 +232,8 @@ static void redudp_drop_client(redudp_client *client)
-                       redudp_log_errno(client, LOG_ERR, "event_del");
-               redsocks_close(fd);
-       }
-+      if (client->sender_fd != -1)
-+              bound_udp4_put(&client->destaddr);
-       list_for_each_entry_safe(q, tmp, &client->queue, list) {
-               list_del(&q->list);
-               free(q);
-@@ -344,7 +474,8 @@ static void redudp_relay_connected(struct bufferevent *buffev, void *_arg)
-       redudp_client *client = _arg;
-       int do_password = socks5_is_valid_cred(client->instance->config.login, client->instance->config.password);
-       int error;
--      redudp_log_error(client, LOG_DEBUG, "<trace>");
-+      char relayaddr_str[RED_INET_ADDRSTRLEN];
-+      redudp_log_error(client, LOG_DEBUG, "via %s", red_inet_ntop(&client->instance->config.relayaddr, relayaddr_str, sizeof(relayaddr_str)));
-       if (!red_is_socket_connected_ok(buffev)) {
-               redudp_log_errno(client, LOG_NOTICE, "red_is_socket_connected_ok");
-@@ -382,7 +513,7 @@ static void redudp_timeout(int fd, short what, void *_arg)
-       redudp_drop_client(client);
- }
--static void redudp_first_pkt_from_client(redudp_instance *self, struct sockaddr_in *clientaddr, char *buf, size_t pktlen)
-+static void redudp_first_pkt_from_client(redudp_instance *self, struct sockaddr_in *clientaddr, struct sockaddr_in *destaddr, char *buf, size_t pktlen)
- {
-       redudp_client *client = calloc(1, sizeof(*client));
-@@ -395,9 +526,13 @@ static void redudp_first_pkt_from_client(redudp_instance *self, struct sockaddr_
-       INIT_LIST_HEAD(&client->queue);
-       client->instance = self;
-       memcpy(&client->clientaddr, clientaddr, sizeof(*clientaddr));
-+      if (destaddr)
-+              memcpy(&client->destaddr, destaddr, sizeof(client->destaddr));
-       evtimer_set(&client->timeout, redudp_timeout, client);
-       // XXX: self->relay_ss->init(client);
-+      client->sender_fd = -1; // it's postponed until socks-server replies to avoid trivial DoS
-+
-       client->relay = red_connect_relay(&client->instance->config.relayaddr,
-                                         redudp_relay_connected, redudp_relay_error, client);
-       if (!client->relay)
-@@ -431,7 +566,7 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
-       assert(fd == EVENT_FD(&client->udprelay));
--      pktlen = red_recv_udp_pkt(fd, pkt.buf, sizeof(pkt.buf), &udprelayaddr);
-+      pktlen = red_recv_udp_pkt(fd, pkt.buf, sizeof(pkt.buf), &udprelayaddr, NULL);
-       if (pktlen == -1)
-               return;
-@@ -455,8 +590,8 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
-               return;
-       }
--      if (pkt.header.ip.port != client->instance->config.destaddr.sin_port ||
--          pkt.header.ip.addr != client->instance->config.destaddr.sin_addr.s_addr)
-+      if (pkt.header.ip.port != get_destaddr(client)->sin_port ||
-+          pkt.header.ip.addr != get_destaddr(client)->sin_addr.s_addr)
-       {
-               char buf[RED_INET_ADDRSTRLEN];
-               struct sockaddr_in pktaddr = {
-@@ -472,8 +607,18 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
-       redsocks_time(&client->last_relay_event);
-       redudp_bump_timeout(client);
-+      if (do_tproxy(client->instance) && client->sender_fd == -1) {
-+              client->sender_fd = bound_udp4_get(&client->destaddr);
-+              if (client->sender_fd == -1) {
-+                      redudp_log_error(client, LOG_WARNING, "bound_udp4_get failure");
-+                      return;
-+              }
-+      }
-+
-       fwdlen = pktlen - sizeof(pkt.header);
--      outgoing = sendto(EVENT_FD(&client->instance->listener),
-+      outgoing = sendto(do_tproxy(client->instance)
-+                            ? client->sender_fd
-+                            : EVENT_FD(&client->instance->listener),
-                         pkt.buf + sizeof(pkt.header), fwdlen, 0,
-                         (struct sockaddr*)&client->clientaddr, sizeof(client->clientaddr));
-       if (outgoing != fwdlen) {
-@@ -486,18 +631,21 @@ static void redudp_pkt_from_socks(int fd, short what, void *_arg)
- static void redudp_pkt_from_client(int fd, short what, void *_arg)
- {
-       redudp_instance *self = _arg;
--      struct sockaddr_in clientaddr;
-+      struct sockaddr_in clientaddr, destaddr, *pdestaddr;
-       char buf[0xFFFF]; // UDP packet can't be larger then that
-       ssize_t pktlen;
-       redudp_client *tmp, *client = NULL;
-+      pdestaddr = do_tproxy(self) ? &destaddr : NULL;
-+
-       assert(fd == EVENT_FD(&self->listener));
--      pktlen = red_recv_udp_pkt(fd, buf, sizeof(buf), &clientaddr);
-+      pktlen = red_recv_udp_pkt(fd, buf, sizeof(buf), &clientaddr, pdestaddr);
-       if (pktlen == -1)
-               return;
-       // TODO: this lookup may be SLOOOOOW.
-       list_for_each_entry(tmp, &self->clients, list) {
-+              // TODO: check destaddr
-               if (0 == memcmp(&clientaddr, &tmp->clientaddr, sizeof(clientaddr))) {
-                       client = tmp;
-                       break;
-@@ -515,7 +663,7 @@ static void redudp_pkt_from_client(int fd, short what, void *_arg)
-               }
-       }
-       else {
--              redudp_first_pkt_from_client(self, &clientaddr, buf, pktlen);
-+              redudp_first_pkt_from_client(self, &clientaddr, pdestaddr, buf, pktlen);
-       }
- }
-@@ -554,7 +702,6 @@ static int redudp_onenter(parser_section *section)
-       instance->config.relayaddr.sin_family = AF_INET;
-       instance->config.relayaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-       instance->config.destaddr.sin_family = AF_INET;
--      instance->config.destaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-       instance->config.max_pktqueue = 5;
-       instance->config.udp_timeout = 30;
-       instance->config.udp_timeout_stream = 180;
-@@ -614,6 +761,28 @@ static int redudp_init_instance(redudp_instance *instance)
-               goto fail;
-       }
-+      if (do_tproxy(instance)) {
-+              int on = 1;
-+              char buf[RED_INET_ADDRSTRLEN];
-+              // iptables TPROXY target does not send packets to non-transparent sockets
-+              if (0 != redudp_transparent(fd))
-+                      goto fail;
-+
-+              error = setsockopt(fd, SOL_IP, IP_RECVORIGDSTADDR, &on, sizeof(on));
-+              if (error) {
-+                      log_errno(LOG_ERR, "setsockopt(listener, SOL_IP, IP_RECVORIGDSTADDR)");
-+                      goto fail;
-+              }
-+
-+              log_error(LOG_DEBUG, "redudp @ %s: TPROXY", red_inet_ntop(&instance->config.bindaddr, buf, sizeof(buf)));
-+      }
-+      else {
-+              char buf1[RED_INET_ADDRSTRLEN], buf2[RED_INET_ADDRSTRLEN];
-+              log_error(LOG_DEBUG, "redudp @ %s: destaddr=%s",
-+                      red_inet_ntop(&instance->config.bindaddr, buf1, sizeof(buf1)),
-+                      red_inet_ntop(&instance->config.destaddr, buf2, sizeof(buf2)));
-+      }
-+
-       error = bind(fd, (struct sockaddr*)&instance->config.bindaddr, sizeof(instance->config.bindaddr));
-       if (error) {
-               log_errno(LOG_ERR, "bind");
-diff --git a/redudp.h b/redudp.h
-index 308bd33..3f1d9d1 100644
---- a/redudp.h
-+++ b/redudp.h
-@@ -24,6 +24,8 @@ typedef struct redudp_client_t {
-       list_head           list;
-       redudp_instance    *instance;
-       struct sockaddr_in  clientaddr;
-+      struct sockaddr_in  destaddr;
-+      int                 sender_fd; // shared between several clients socket (bound to `destaddr`)
-       struct event        timeout;
-       struct bufferevent *relay;
-       struct event        udprelay;
-diff --git a/utils.c b/utils.c
-index 6e1f3af..afdeea8 100644
---- a/utils.c
-+++ b/utils.c
-@@ -26,17 +26,54 @@
- #include "utils.h"
- #include "redsocks.h" // for redsocks_close
--int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *inaddr)
-+int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *inaddr, struct sockaddr_in *toaddr)
- {
-       socklen_t addrlen = sizeof(*inaddr);
-       ssize_t pktlen;
--
--      pktlen = recvfrom(fd, buf, buflen, 0, (struct sockaddr*)inaddr, &addrlen);
-+      struct msghdr msg;
-+      struct iovec io;
-+      char control[1024];
-+
-+      memset(&msg, 0, sizeof(msg));
-+      msg.msg_name = inaddr;
-+      msg.msg_namelen = sizeof(*inaddr);
-+      msg.msg_iov = &io;
-+      msg.msg_iovlen = 1;
-+      msg.msg_control = control;
-+      msg.msg_controllen = sizeof(control);
-+      io.iov_base = buf;
-+      io.iov_len = buflen;
-+
-+      pktlen = recvmsg(fd, &msg, 0);
-       if (pktlen == -1) {
-               log_errno(LOG_WARNING, "recvfrom");
-               return -1;
-       }
-+      if (toaddr) {
-+              memset(toaddr, 0, sizeof(*toaddr));
-+              for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-+                      if (
-+                              cmsg->cmsg_level == SOL_IP &&
-+                              cmsg->cmsg_type == IP_ORIGDSTADDR &&
-+                              cmsg->cmsg_len >= CMSG_LEN(sizeof(*toaddr))
-+                      ) {
-+                              struct sockaddr_in* cmsgaddr = (struct sockaddr_in*)CMSG_DATA(cmsg);
-+                              char buf[RED_INET_ADDRSTRLEN];
-+                              log_error(LOG_DEBUG, "IP_ORIGDSTADDR: %s", red_inet_ntop(cmsgaddr, buf, sizeof(buf)));
-+                              memcpy(toaddr, cmsgaddr, sizeof(*toaddr));
-+                      }
-+                      else {
-+                              log_error(LOG_WARNING, "unexepcted cmsg (level,type) = (%d,%d)",
-+                                      cmsg->cmsg_level, cmsg->cmsg_type);
-+                      }
-+              }
-+              if (toaddr->sin_family != AF_INET) {
-+                      log_error(LOG_WARNING, "(SOL_IP, IP_ORIGDSTADDR) not found");
-+                      return -1;
-+              }
-+      }
-+
-       if (addrlen != sizeof(*inaddr)) {
-               log_error(LOG_WARNING, "unexpected address length %u instead of %zu", addrlen, sizeof(*inaddr));
-               return -1;
-diff --git a/utils.h b/utils.h
-index d3af00f..c2277e9 100644
---- a/utils.h
-+++ b/utils.h
-@@ -44,7 +44,7 @@ char *redsocks_evbuffer_readline(struct evbuffer *buf);
- struct bufferevent* red_connect_relay(struct sockaddr_in *addr, evbuffercb writecb, everrorcb errorcb, void *cbarg);
- int red_socket_geterrno(struct bufferevent *buffev);
- int red_is_socket_connected_ok(struct bufferevent *buffev);
--int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *inaddr);
-+int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *fromaddr, struct sockaddr_in *toaddr);
- int fcntl_nonblock(int fd);
--- 
-1.9.1
-
diff --git a/net/redsocks/patches/0004-Fix-transposition-of-memset-parameters.patch b/net/redsocks/patches/0004-Fix-transposition-of-memset-parameters.patch
deleted file mode 100644 (file)
index cb6fa1e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-From b60b492602448b59aea194afd4991910d3613e5c Mon Sep 17 00:00:00 2001
-From: Cody Schafer <jmesmon@gmail.com>
-Date: Tue, 24 Apr 2012 04:33:13 -0500
-Subject: [PATCH 04/12] Fix transposition of memset parameters.
-
----
- utils.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/utils.c b/utils.c
-index afdeea8..31c6894 100644
---- a/utils.c
-+++ b/utils.c
-@@ -222,7 +222,7 @@ char *red_inet_ntop(const struct sockaddr_in* sa, char* buffer, size_t buffer_si
-       assert(buffer_size >= sizeof(placeholder));
--      memset(buffer, buffer_size, 0);
-+      memset(buffer, 0, buffer_size);
-       if (sa->sin_family == AF_INET) {
-               retval = inet_ntop(AF_INET, &sa->sin_addr, buffer, buffer_size);
-               port = ((struct sockaddr_in*)sa)->sin_port;
--- 
-1.9.1
-
diff --git a/net/redsocks/patches/0005-Fix-compilation-on-Ubuntu-10.04-LTS-and-hopefully-De.patch b/net/redsocks/patches/0005-Fix-compilation-on-Ubuntu-10.04-LTS-and-hopefully-De.patch
deleted file mode 100644 (file)
index f0f09aa..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-From 18e2b5ed1ffb3e7c5dfec8ff41b3027163f680ed Mon Sep 17 00:00:00 2001
-From: Leonid Evdokimov <leon@darkk.net.ru>
-Date: Wed, 12 Sep 2012 02:05:39 +0400
-Subject: [PATCH 09/12] Fix compilation on Ubuntu 10.04 LTS and (hopefully)
- Debian squeeze[1]
-
-fixes #28, fixes #22, fixes #24
-[1] current "stable" release
----
- libc-compat.h     | 25 +++++++++++++++++++++++++
- libevent-compat.h | 11 +++++++++++
- redsocks.c        |  1 +
- redudp.c          |  1 +
- utils.c           |  1 +
- 5 files changed, 39 insertions(+)
- create mode 100644 libc-compat.h
- create mode 100644 libevent-compat.h
-
-diff --git a/libc-compat.h b/libc-compat.h
-new file mode 100644
-index 0000000..adcf63b
---- /dev/null
-+++ b/libc-compat.h
-@@ -0,0 +1,25 @@
-+#ifndef UUID_67C91670_FCCB_4855_BDF7_609F1EECB8B4
-+#define UUID_67C91670_FCCB_4855_BDF7_609F1EECB8B4
-+
-+/* all these definitions, are included into bits/in.h from libc6-dev 2.15-0ubuntu10
-+ * from Ubuntu 12.04 and is not included into libc6-dev 2.11.1-0ubuntu7.10 from
-+ * Ubuntu 10.04.
-+ * linux/in.h is not included directly because of lots of redefinitions,
-+ * extracting single value from linux/in.h is not done because it looks like
-+ * autotools reinvention */
-+#ifndef IP_ORIGDSTADDR
-+#   warning Using hardcoded value for IP_ORIGDSTADDR as libc headers do not define it.
-+#   define IP_ORIGDSTADDR 20
-+#endif
-+
-+#ifndef IP_RECVORIGDSTADDR
-+#   warning Using hardcoded value for IP_RECVORIGDSTADDR as libc headers do not define it.
-+#   define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
-+#endif
-+
-+#ifndef IP_TRANSPARENT
-+#   warning Using hardcoded value for IP_TRANSPARENT as libc headers do not define it.
-+#   define IP_TRANSPARENT 19
-+#endif
-+
-+#endif // 67C91670_FCCB_4855_BDF7_609F1EECB8B4
-diff --git a/libevent-compat.h b/libevent-compat.h
-new file mode 100644
-index 0000000..a7f1ca1
---- /dev/null
-+++ b/libevent-compat.h
-@@ -0,0 +1,11 @@
-+#ifndef UUID_FC148CFA_5ECC_488E_8A62_CD39406C9F1E
-+#define UUID_FC148CFA_5ECC_488E_8A62_CD39406C9F1E
-+
-+/* evutil_socket_t is macros in libevent-2.0, not typedef, libevent-1.4 is
-+ * still supported because of Ubuntu 10.04 LTS */
-+#ifndef evutil_socket_t
-+#   warning Using hardcoded value for evutil_socket_t as libevent headers do not define it.
-+#   define evutil_socket_t int
-+#endif
-+
-+#endif // FC148CFA_5ECC_488E_8A62_CD39406C9F1E
-diff --git a/redsocks.c b/redsocks.c
-index ba5eab2..878576f 100644
---- a/redsocks.c
-+++ b/redsocks.c
-@@ -33,6 +33,7 @@
- #include "base.h"
- #include "redsocks.h"
- #include "utils.h"
-+#include "libevent-compat.h"
- #define REDSOCKS_RELAY_HALFBUFF  4096
-diff --git a/redudp.c b/redudp.c
-index 262af3e..05460dc 100644
---- a/redudp.c
-+++ b/redudp.c
-@@ -32,6 +32,7 @@
- #include "main.h"
- #include "redsocks.h"
- #include "redudp.h"
-+#include "libc-compat.h"
- #define redudp_log_error(client, prio, msg...) \
-       redsocks_log_write_plain(__FILE__, __LINE__, __func__, 0, &(client)->clientaddr, get_destaddr(client), prio, ## msg)
-diff --git a/utils.c b/utils.c
-index 31c6894..7de3969 100644
---- a/utils.c
-+++ b/utils.c
-@@ -25,6 +25,7 @@
- #include "log.h"
- #include "utils.h"
- #include "redsocks.h" // for redsocks_close
-+#include "libc-compat.h"
- int red_recv_udp_pkt(int fd, char *buf, size_t buflen, struct sockaddr_in *inaddr, struct sockaddr_in *toaddr)
- {
--- 
-1.9.1
-
index 1994befa6caac12cb1adafe6a286709a54083263..987085f0ddaaaa407a2988a5bb2c7680d25c57d0 100644 (file)
@@ -6,7 +6,7 @@ Forwared: no
 Last-Update: 2013-04-23
 --- a/main.c
 +++ b/main.c
-@@ -39,7 +39,7 @@
+@@ -39,7 +39,7 @@ app_subsys *subsystems[] = {
        &dnstc_subsys,
  };
  
git clone https://git.99rst.org/PROJECT