--- /dev/null
+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)
--- /dev/null
+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;
+ }
+