mirror of
https://github.com/openwrt/packages.git
synced 2025-02-23 14:46:15 +00:00
Fix segmentation fault with newer musl and improve throughput. Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
115 lines
3.5 KiB
Diff
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;
|
|
}
|
|
|