microsocks: backport upstream fixes
Fix segmentation fault with newer musl and improve throughput. Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
parent
955976cee7
commit
77a7324de5
|
@ -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)?
|
||||
|
|
|
@ -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
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue