penguin/tinyproxy

An L4 proxy designed to act as a tiny transparent shim

commit fc3b1e1595fd8bc8f0b7287646f4a9ba5a3448e2

author斟酌 鵬兄 <tgckpg@gmail.com>
date2026-06-05T19:50:24Z
subjectFixed client_addr regression
commit fc3b1e1595fd8bc8f0b7287646f4a9ba5a3448e2
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date:   2026-06-05T19:50:24Z

    Fixed client_addr regression
---
 src/stream_builtin.c | 23 +++++++++++++++++++++--
 src/x_builtins.c     |  7 +------
 src/x_builtins.h     |  1 +
 3 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/stream_builtin.c b/src/stream_builtin.c
index f0f406c..21bf9a0 100644
--- a/src/stream_builtin.c
+++ b/src/stream_builtin.c
@@ -15,7 +15,7 @@ static void builtin_client_read_cb(struct bufferevent *bev, void *arg)
 	evbuffer_drain(input, evbuffer_get_length(input));
 }
 
-static void builtin_close_after_write_cb(struct bufferevent *bev, void *arg)
+static void builtin_http_close_after_write_cb(struct bufferevent *bev, void *arg)
 {
 	conn_t *conn = arg;
 	struct evbuffer *output = bufferevent_get_output(bev);
@@ -28,6 +28,15 @@ static void builtin_close_after_write_cb(struct bufferevent *bev, void *arg)
 	conn->close_after_client_eof = true;
 }
 
+static void builtin_close_after_write_cb(struct bufferevent *bev, void *arg)
+{
+	conn_t *conn = arg;
+
+	if (evbuffer_get_length(bufferevent_get_output(bev)) == 0) {
+		free_conn(conn);
+	}
+}
+
 static const char *stream_client_addr_string(conn_t *conn, char *buf, size_t buf_len)
 {
 	struct sockaddr_storage ss;
@@ -107,11 +116,21 @@ int start_stream_builtin(conn_t *conn)
 
 	switch (res.action) {
 	case X_BUILTIN_ACTION_CLOSE:
+		if (res.data_len > 0) {
+			bufferevent_write(conn->client, res.data, res.data_len);
+			bufferevent_setcb(conn->client, NULL, builtin_close_after_write_cb, stream_client_event_cb, conn);
+			bufferevent_enable(conn->client, EV_WRITE);
+		} else {
+			free_conn(conn);
+		}
+		return 0;
+
+	case X_BUILTIN_ACTION_HTTP_RESP:
 		if (res.data_len > 0) {
 			bufferevent_setcb(
 				conn->client,
 				builtin_client_read_cb,
-				builtin_close_after_write_cb,
+				builtin_http_close_after_write_cb,
 				stream_client_event_cb,
 				conn
 			);
diff --git a/src/x_builtins.c b/src/x_builtins.c
index 5969250..1ddeb05 100644
--- a/src/x_builtins.c
+++ b/src/x_builtins.c
@@ -41,11 +41,6 @@ int x_builtin_parse(const char *s, enum x_builtin_upstream *out)
 		return 0;
 	}
 
-	if (strcmp(s, "close") == 0) {
-		*out = X_BUILTIN_CLOSE;
-		return 0;
-	}
-
 	return -EINVAL;
 }
 
@@ -108,7 +103,7 @@ int x_builtin_handle(
 		memcpy(res->data, http_ok, sizeof(http_ok) - 1);
 		res->data_len = sizeof(http_ok) - 1;
 
-		res->action = X_BUILTIN_ACTION_CLOSE;
+		res->action = X_BUILTIN_ACTION_HTTP_RESP;
 		return 0;
 	}
 
diff --git a/src/x_builtins.h b/src/x_builtins.h
index bcc5a77..56a4df8 100644
--- a/src/x_builtins.h
+++ b/src/x_builtins.h
@@ -18,6 +18,7 @@ enum x_builtin_action {
 	X_BUILTIN_ACTION_CLOSE,
 	X_BUILTIN_ACTION_DISCARD,
 	X_BUILTIN_ACTION_HANG,
+	X_BUILTIN_ACTION_HTTP_RESP,
 };
 
 struct x_builtin_request {