Skip to content

Buffer rework - #622

Open
rofl0r wants to merge 2 commits into
tinyproxy:masterfrom
rofl0r:buffer_rework
Open

rofl0r wants to merge 2 commits into
tinyproxy:masterfrom
rofl0r:buffer_rework

Conversation

@rofl0r

@rofl0r rofl0r commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

No description provided.

rofl0r added 2 commits August 1, 2026 23:59
The old buffer implementation was written in the 90ies when tinyproxy
primarily forwarded plain HTTP requests. It used a linked list of
bufline_s structures optimized for line-based text processing of
HTTP request and response lines.

A typical tinyproxy instance in 2026 serves 99% of requests via the
CONNECT method to HTTPS endpoints. The old design is ill-suited for
this workload: it performs dynamic allocation for each chunk of data
read from the socket, and removes complete lines from the linked list
as they are sent. This design assumes line-oriented text processing
rather than transparent byte copying between sockets.

Replace the linked-list implementation with a contiguous buffer.
The buffer struct is allocated as a single block with the data area
immediately following the struct in memory. This eliminates per-chunk
allocation overhead and simplifies compaction.

Remove add_to_buffer() from the public API. The old line-oriented
API is replaced by direct read_buffer()/write_buffer() calls
through the poll-driven relay_connection() loop.

Add buffer_space() to buffer.h. This function returns the number
of bytes available in the buffer for writing.

Simplify error handling in write_buffer(). Remove the explicit
ENOBUFS/ENOMEM cases. The default error path now handles all
unexpected errors uniformly.

Update relay_connection() in reqs.c to use buffer_space()
instead of buffer_size() when deciding whether to enable
MYPOLL_READ events.

Remove unused buffer.h includes from html-error.c and main.c.
Remove the HTTP_LINE_LENGTH constant from reqs.c.
Increase BUFFER_CAPACITY from 16KB to 64KB. This provides
headroom for large TLS certificate chains and reduces the
frequency of memmove() compaction calls.

Add BUFFER_WATER_MARK constant at 16KB. Modify buffer_space()
to return zero when remaining capacity falls below the water
mark. This prevents read() from being called when the buffer
cannot hold a full TLS record.

The water mark acts as a flow-control threshold. It ensures
the poll loop only enables MYPOLL_READ when there is guaranteed
space for a complete TLS record, avoiding partial reads that
could cause server-side connection resets (see 0253c07).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant