0
0
mirror of https://github.com/openwrt/packages.git synced 2025-02-23 14:46:15 +00:00
packages/net/microsocks/patches/003-improve-throughput-in-copyloop-using-bigger-buffer.patch
Tianling Shen 77a7324de5 microsocks: backport upstream fixes
Fix segmentation fault with newer musl and improve throughput.

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
2024-12-09 11:17:24 +02:00

115 lines
3.5 KiB
Diff

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;
}