From 77a7324de54e175029fa7ad051a3a17d1806e03e Mon Sep 17 00:00:00 2001 From: Tianling Shen Date: Wed, 4 Dec 2024 13:33:13 +0800 Subject: [PATCH] microsocks: backport upstream fixes Fix segmentation fault with newer musl and improve throughput. Signed-off-by: Tianling Shen --- net/microsocks/Makefile | 2 +- ...use-a-bigger-thread-stack-by-default.patch | 24 ++++ ...bout-shadow-declaration-of-bind_addr.patch | 22 ++++ ...hput-in-copyloop-using-bigger-buffer.patch | 114 ++++++++++++++++++ 4 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 net/microsocks/patches/001-use-a-bigger-thread-stack-by-default.patch create mode 100644 net/microsocks/patches/002-mute-warning-about-shadow-declaration-of-bind_addr.patch create mode 100644 net/microsocks/patches/003-improve-throughput-in-copyloop-using-bigger-buffer.patch diff --git a/net/microsocks/Makefile b/net/microsocks/Makefile index 79eea2e6af..b2adbc20c1 100644 --- a/net/microsocks/Makefile +++ b/net/microsocks/Makefile @@ -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 index 0000000000..3defe5db23 --- /dev/null +++ b/net/microsocks/patches/001-use-a-bigger-thread-stack-by-default.patch @@ -0,0 +1,24 @@ +From c81760cc3f1b6db22c7c9694efe7f3be115c2caf Mon Sep 17 00:00:00 2001 +From: rofl0r +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 index 0000000000..8d298bd7fa --- /dev/null +++ b/net/microsocks/patches/002-mute-warning-about-shadow-declaration-of-bind_addr.patch @@ -0,0 +1,22 @@ +From 0343813e0410b469d591bc61b9a546ee2c2c15f6 Mon Sep 17 00:00:00 2001 +From: rofl0r +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 index 0000000000..dfee5c933e --- /dev/null +++ b/net/microsocks/patches/003-improve-throughput-in-copyloop-using-bigger-buffer.patch @@ -0,0 +1,114 @@ +From 98421a21c4adc4c77c0cf3a5d650cc28ad3e0107 Mon Sep 17 00:00:00 2001 +From: rofl0r +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; + } +