Skip to content

perf(proxy): add sync.Pool for UDP buffers#277

Draft
LaurenceJJones wants to merge 1 commit intofosrl:devfrom
LaurenceJJones:refactor/proxy-udp-buffer-pool
Draft

perf(proxy): add sync.Pool for UDP buffers#277
LaurenceJJones wants to merge 1 commit intofosrl:devfrom
LaurenceJJones:refactor/proxy-udp-buffer-pool

Conversation

@LaurenceJJones
Copy link
Copy Markdown
Member

Community Contribution License Agreement

By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.

Description

  • Add udpBufferPool for reusable 65507-byte UDP packet buffers
  • Add getUDPBuffer() and putUDPBuffer() helper functions
  • Clear buffer contents before returning to pool to prevent data leakage
  • Apply pooling to both main handler buffer and per-client goroutine buffers
  • Reduces GC pressure from frequent large allocations during UDP proxying

How to test?

Internal code changes.

- Add udpBufferPool for reusable 65507-byte UDP packet buffers
- Add getUDPBuffer() and putUDPBuffer() helper functions
- Clear buffer contents before returning to pool to prevent data leakage
- Apply pooling to both main handler buffer and per-client goroutine buffers
- Reduces GC pressure from frequent large allocations during UDP proxying
@strausmann
Copy link
Copy Markdown

We can confirm the UDP buffer allocation issue described in this PR from our production environment.

On an affected Newt instance (details in #268), we observed 11+ simultaneous UDP connections to our DNS resolver, each with its own file descriptor — no reuse:

UDP: fd=86   -> dns-resolver:853
UDP: fd=479  -> dns-resolver:853
UDP: fd=1057 -> dns-resolver:853
UDP: fd=1232 -> dns-resolver:853
UDP: fd=2749 -> dns-resolver:853

Under high TCP forwarding load (SMTP targets with health checks), DNS lookups are very frequent, which amplifies the buffer allocation issue significantly. In proxy/manager.go, every new TCP connection in handleTCPProxy triggers a net.Dial which performs DNS resolution — and under our workload we saw 246 TCP connections within a 500-line log window.

The sync.Pool approach in this PR would directly address what we're seeing on the UDP side. Combined with a fix for the TCP connection leak (#268), it would significantly reduce the memory and FD growth we're experiencing.

Would love to see this merged.

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.

2 participants