microsocks: backport upstream fixes
authorTianling Shen <cnsztl@immortalwrt.org>
Wed, 4 Dec 2024 05:33:13 +0000 (13:33 +0800)
committerJosef Schlehofer <pepe.schlehofer@gmail.com>
Mon, 9 Dec 2024 09:17:24 +0000 (11:17 +0200)
Fix segmentation fault with newer musl and improve throughput.

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
net/microsocks/Makefile
net/microsocks/patches/001-use-a-bigger-thread-stack-by-default.patch [new file with mode: 0644]
net/microsocks/patches/002-mute-warning-about-shadow-declaration-of-bind_addr.patch [new file with mode: 0644]
net/microsocks/patches/003-improve-throughput-in-copyloop-using-bigger-buffer.patch [new file with mode: 0644]

index 79eea2e6af6eabc5977c92e41fd52e34f50bb89b..b2adbc20c1ffa763750d113fbcd185d30e8b50f6 100644 (file)
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=microsocks
 PKG_VERSION:=1.0.4
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/rofl0r/microsocks/tar.gz/v$(PKG_VERSION)?
diff --git a/net/microsocks/patches/001-use-a-bigger-thread-stack-by-default.patch b/net/microsocks/patches/001-use-a-bigger-thread-stack-by-default.patch
new file mode 100644 (file)
index 0000000..3defe5d
--- /dev/null
@@ -0,0 +1,24 @@
+From c81760cc3f1b6db22c7c9694efe7f3be115c2caf Mon Sep 17 00:00:00 2001
+From: rofl0r <rofl0r@users.noreply.github.com>
+Date: Fri, 17 May 2024 14:38:16 +0000
+Subject: [PATCH] use a bigger thread stack by default
+
+apparently newer musl versions require more stack for the TCP-based
+DNS resolver.
+
+closes #73
+---
+ sockssrv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sockssrv.c
++++ b/sockssrv.c
+@@ -47,7 +47,7 @@
+ #endif
+ #ifdef PTHREAD_STACK_MIN
+-#define THREAD_STACK_SIZE MAX(8*1024, PTHREAD_STACK_MIN)
++#define THREAD_STACK_SIZE MAX(16*1024, PTHREAD_STACK_MIN)
+ #else
+ #define THREAD_STACK_SIZE 64*1024
+ #endif
diff --git a/net/microsocks/patches/002-mute-warning-about-shadow-declaration-of-bind_addr.patch b/net/microsocks/patches/002-mute-warning-about-shadow-declaration-of-bind_addr.patch
new file mode 100644 (file)
index 0000000..8d298bd
--- /dev/null
@@ -0,0 +1,22 @@
+From 0343813e0410b469d591bc61b9a546ee2c2c15f6 Mon Sep 17 00:00:00 2001
+From: rofl0r <rofl0r@users.noreply.github.com>
+Date: Fri, 17 May 2024 14:40:11 +0000
+Subject: [PATCH] mute warning about shadow declaration of bind_addr
+
+---
+ sockssrv.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sockssrv.c
++++ b/sockssrv.c
+@@ -112,8 +112,8 @@ struct thread {
+ static void dolog(const char* fmt, ...) { }
+ #endif
+-static struct addrinfo* addr_choose(struct addrinfo* list, union sockaddr_union* bind_addr) {
+-      int af = SOCKADDR_UNION_AF(bind_addr);
++static struct addrinfo* addr_choose(struct addrinfo* list, union sockaddr_union* bindaddr) {
++      int af = SOCKADDR_UNION_AF(bindaddr);
+       if(af == AF_UNSPEC) return list;
+       struct addrinfo* p;
+       for(p=list; p; p=p->ai_next)
diff --git a/net/microsocks/patches/003-improve-throughput-in-copyloop-using-bigger-buffer.patch b/net/microsocks/patches/003-improve-throughput-in-copyloop-using-bigger-buffer.patch
new file mode 100644 (file)
index 0000000..dfee5c9
--- /dev/null
@@ -0,0 +1,114 @@
+From 98421a21c4adc4c77c0cf3a5d650cc28ad3e0107 Mon Sep 17 00:00:00 2001
+From: rofl0r <rofl0r@users.noreply.github.com>
+Date: Fri, 24 May 2024 23:02:34 +0000
+Subject: [PATCH] improve throughput in copyloop() using bigger buffer
+
+- refactored clientthread to put the handshake code into its own
+  function, since it used its own 1K stack buffer.
+  by returning from the function before calling copyloop, we have
+  that space available in the new stackframe.
+- since getaddrinfo() was the main stack consumer in the entire
+  code, we can safely use at least half the available thread
+  stack size for the copyloop to achieve higher throughput.
+  in my testing with pyhttpd it turned out that 64k is the sweet
+  spot to have minimal syscall overhead, but 16k is very close,
+  and it allows us to keep the minimal memory usage profile.
+
+this is in response to https://github.com/rofl0r/microsocks/issues/58#issuecomment-2118389063
+which links to a repo that tests different socks5 servers
+performance on gigabit links.
+
+also closes #10
+---
+ sockssrv.c | 35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+--- a/sockssrv.c
++++ b/sockssrv.c
+@@ -44,6 +44,7 @@
+ #ifndef MAX
+ #define MAX(x, y) ((x) > (y) ? (x) : (y))
++#define MIN(x, y) ((x) < (y) ? (x) : (y))
+ #endif
+ #ifdef PTHREAD_STACK_MIN
+@@ -282,7 +283,10 @@ static void copyloop(int fd1, int fd2) {
+               }
+               int infd = (fds[0].revents & POLLIN) ? fd1 : fd2;
+               int outfd = infd == fd2 ? fd1 : fd2;
+-              char buf[1024];
++              /* since the biggest stack consumer in the entire code is
++                 libc's getaddrinfo(), we can safely use at least half the
++                 available stacksize to improve throughput. */
++              char buf[MIN(16*1024, THREAD_STACK_SIZE/2)];
+               ssize_t sent = 0, n = read(infd, buf, sizeof buf);
+               if(n <= 0) return;
+               while(sent < n) {
+@@ -310,14 +314,12 @@ static enum errorcode check_credentials(
+       return EC_NOT_ALLOWED;
+ }
+-static void* clientthread(void *data) {
+-      struct thread *t = data;
+-      t->state = SS_1_CONNECTED;
++static int handshake(struct thread *t) {
+       unsigned char buf[1024];
+       ssize_t n;
+       int ret;
+-      int remotefd = -1;
+       enum authmethod am;
++      t->state = SS_1_CONNECTED;
+       while((n = recv(t->client.fd, buf, sizeof buf, 0)) > 0) {
+               switch(t->state) {
+                       case SS_1_CONNECTED:
+@@ -325,13 +327,13 @@ static void* clientthread(void *data) {
+                               if(am == AM_NO_AUTH) t->state = SS_3_AUTHED;
+                               else if (am == AM_USERNAME) t->state = SS_2_NEED_AUTH;
+                               send_auth_response(t->client.fd, 5, am);
+-                              if(am == AM_INVALID) goto breakloop;
++                              if(am == AM_INVALID) return -1;
+                               break;
+                       case SS_2_NEED_AUTH:
+                               ret = check_credentials(buf, n);
+                               send_auth_response(t->client.fd, 1, ret);
+                               if(ret != EC_SUCCESS)
+-                                      goto breakloop;
++                                      return -1;
+                               t->state = SS_3_AUTHED;
+                               if(auth_ips && !pthread_rwlock_wrlock(&auth_ips_lock)) {
+                                       if(!is_in_authed_list(&t->client.addr))
+@@ -343,23 +345,24 @@ static void* clientthread(void *data) {
+                               ret = connect_socks_target(buf, n, &t->client);
+                               if(ret < 0) {
+                                       send_error(t->client.fd, ret*-1);
+-                                      goto breakloop;
++                                      return -1;
+                               }
+-                              remotefd = ret;
+                               send_error(t->client.fd, EC_SUCCESS);
+-                              copyloop(t->client.fd, remotefd);
+-                              goto breakloop;
+-
++                              return ret;
+               }
+       }
+-breakloop:
++      return -1;
++}
+-      if(remotefd != -1)
++static void* clientthread(void *data) {
++      struct thread *t = data;
++      int remotefd = handshake(t);
++      if(remotefd != -1) {
++              copyloop(t->client.fd, remotefd);
+               close(remotefd);
+-
++      }
+       close(t->client.fd);
+       t->done = 1;
+-
+       return 0;
+ }